From 73779f7631d41f16f89c62cae09a1b27d8189dc3 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Wed, 19 Sep 2012 18:00:32 +0900
Subject: Make readUnigramsAndBigramsBinary read linked-list nodes.
Change-Id: I07ae036b0b06e71d7a18f2bf11e4692cd4213568
---
.../inputmethod/latin/makedict/BinaryDictIOUtils.java | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 7a1b9dcb7..406071071 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -92,7 +92,18 @@ public class BinaryDictIOUtils {
}
if (p.mPosition == p.mNumOfCharGroup) {
- stack.pop();
+ if (formatOptions.mHasLinkedListNode) {
+ final int forwardLinkAddress = buffer.readUnsignedInt24();
+ if (forwardLinkAddress != FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ // the node has a forward link.
+ p.mNumOfCharGroup = Position.NOT_READ_GROUPCOUNT;
+ p.mAddress = forwardLinkAddress;
+ } else {
+ stack.pop();
+ }
+ } else {
+ stack.pop();
+ }
} else {
// the node has more groups.
p.mAddress = buffer.position();
--
cgit v1.2.3-83-g751a
From 66597f5e5f3249f418665c1990fb539d2f5565d5 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Thu, 20 Sep 2012 14:27:33 +0900
Subject: Add deleteWord.
bug: 6669677
Change-Id: I1a5b90ee05e5cffd74a5c140384a3e37c79e7e70
---
.../latin/makedict/BinaryDictIOUtils.java | 22 +++++++++++++
.../latin/makedict/BinaryDictInputOutput.java | 2 +-
.../latin/makedict/BinaryDictIOTests.java | 37 +++++++++++++++++++++-
3 files changed, 59 insertions(+), 2 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 406071071..397532933 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -201,4 +201,26 @@ public class BinaryDictIOUtils {
}
return FormatSpec.NOT_VALID_WORD;
}
+
+ /**
+ * Delete the word from the binary file.
+ *
+ * @param buffer the buffer to write.
+ * @param word the word we delete
+ * @throws IOException
+ * @throws UnsupportedFormatException
+ */
+ public static void deleteWord(final FusionDictionaryBufferInterface buffer,
+ final String word) throws IOException, UnsupportedFormatException {
+ buffer.position(0);
+ final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
+ final int wordPosition = getTerminalPosition(buffer, word);
+ if (wordPosition == FormatSpec.NOT_VALID_WORD) return;
+
+ buffer.position(wordPosition);
+ final int flags = buffer.readUnsignedByte();
+ final int newFlags = flags ^ FormatSpec.FLAG_IS_TERMINAL;
+ buffer.position(wordPosition);
+ buffer.put((byte)newFlags);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 1d3e94bb7..7b8dc5cc5 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -392,7 +392,7 @@ public class BinaryDictInputOutput {
/**
* Helper method to check whether the CharGroup has a parent address.
*/
- private static boolean hasParentAddress(final FormatOptions options) {
+ public static boolean hasParentAddress(final FormatOptions options) {
return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_PARENT_ADDRESS
&& options.mHasParentAddress;
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
index 24776d536..539021f24 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
@@ -25,6 +25,7 @@ import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
import android.util.Log;
import android.util.SparseArray;
@@ -517,7 +518,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
public void testGetTerminalPosition() {
File file = null;
try {
- file = File.createTempFile("runReadUnigrams", ".dict");
+ file = File.createTempFile("testGetTerminalPosition", ".dict");
} catch (IOException e) {
// do nothing
}
@@ -564,4 +565,38 @@ public class BinaryDictIOTests extends AndroidTestCase {
runGetTerminalPosition(buffer, word, i, false);
}
}
+
+ public void testDeleteWord() {
+ File file = null;
+ try {
+ file = File.createTempFile("testGetTerminalPosition", ".dict");
+ } catch (IOException e) {
+ // do nothing
+ }
+ assertNotNull(file);
+
+ final FusionDictionary dict = new FusionDictionary(new Node(),
+ new FusionDictionary.DictionaryOptions(
+ new HashMap(), false, false));
+ addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
+ timeWritingDictToFile(file, dict, VERSION3_WITH_LINKEDLIST_NODE);
+
+ final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY);
+
+ try {
+ MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD,
+ BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(0)));
+ BinaryDictIOUtils.deleteWord(buffer, sWords.get(0));
+ assertEquals(FormatSpec.NOT_VALID_WORD,
+ BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(0)));
+
+ MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD,
+ BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(5)));
+ BinaryDictIOUtils.deleteWord(buffer, sWords.get(5));
+ assertEquals(FormatSpec.NOT_VALID_WORD,
+ BinaryDictIOUtils.getTerminalPosition(buffer, sWords.get(5)));
+ } catch (IOException e) {
+ } catch (UnsupportedFormatException e) {
+ }
+ }
}
--
cgit v1.2.3-83-g751a
From 8ae8c761493867be7364806cdc4d7103a46dc181 Mon Sep 17 00:00:00 2001
From: Satoshi Kataoka
Date: Fri, 21 Sep 2012 15:09:47 +0900
Subject: Cleanup settings
bug: 7200189
Change-Id: Ibfd9254670cde5f4b2b693cc9334ee2845bede59
---
java/res/xml/prefs.xml | 10 +++---
java/res/xml/prefs_for_debug.xml | 6 ++++
.../android/inputmethod/latin/DebugSettings.java | 11 ++++++
.../com/android/inputmethod/latin/Settings.java | 41 +++++++---------------
.../android/inputmethod/latin/SettingsValues.java | 2 +-
5 files changed, 35 insertions(+), 35 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 3e83fc0fc..478dc0f80 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -92,11 +92,6 @@
android:summary="@string/gesture_input_summary"
android:persistent="true"
android:defaultValue="true" />
-
+
diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml
index b926ed065..605a02f07 100644
--- a/java/res/xml/prefs_for_debug.xml
+++ b/java/res/xml/prefs_for_debug.xml
@@ -48,4 +48,10 @@
android:persistent="true"
android:defaultValue="false"
/>
+
+
diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java
index af7649863..1ea14dad5 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettings.java
@@ -23,10 +23,12 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Process;
import android.preference.CheckBoxPreference;
+import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.util.Log;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
+import com.android.inputmethod.research.ResearchLogger;
public class DebugSettings extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
@@ -34,6 +36,7 @@ public class DebugSettings extends PreferenceFragment
private static final String TAG = DebugSettings.class.getSimpleName();
private static final String DEBUG_MODE_KEY = "debug_mode";
public static final String FORCE_NON_DISTINCT_MULTITOUCH_KEY = "force_non_distinct_multitouch";
+ public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
private boolean mServiceNeedsRestart = false;
private CheckBoxPreference mDebugMode;
@@ -45,6 +48,14 @@ public class DebugSettings extends PreferenceFragment
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
prefs.registerOnSharedPreferenceChangeListener(this);
+ final Preference usabilityStudyPref = findPreference(PREF_USABILITY_STUDY_MODE);
+ if (usabilityStudyPref instanceof CheckBoxPreference) {
+ final CheckBoxPreference checkbox = (CheckBoxPreference)usabilityStudyPref;
+ checkbox.setChecked(prefs.getBoolean(PREF_USABILITY_STUDY_MODE,
+ ResearchLogger.DEFAULT_USABILITY_STUDY_MODE));
+ checkbox.setSummary(R.string.settings_warning_researcher_mode);
+ }
+
mServiceNeedsRestart = false;
mDebugMode = (CheckBoxPreference) findPreference(DEBUG_MODE_KEY);
updateDebugMode();
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 9479a88a7..b984ec367 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -39,12 +39,10 @@ import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.research.ResearchLogger;
import com.android.inputmethodcommon.InputMethodSettingsFragment;
public final class Settings extends InputMethodSettingsFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
- public static final boolean ENABLE_INTERNAL_SETTINGS = ProductionFlag.IS_INTERNAL;
// In the same order as xml/prefs.xml
public static final String PREF_GENERAL_SETTINGS = "general_settings";
@@ -58,7 +56,6 @@ public final class Settings extends InputMethodSettingsFragment
public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting";
public static final String PREF_MISC_SETTINGS = "misc_settings";
- public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME =
"last_user_dictionary_write_time";
public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings";
@@ -133,14 +130,6 @@ public final class Settings extends InputMethodSettingsFragment
mAutoCorrectionThresholdPreference =
(ListPreference) findPreference(PREF_AUTO_CORRECTION_THRESHOLD);
mBigramPrediction = (CheckBoxPreference) findPreference(PREF_BIGRAM_PREDICTIONS);
- mDebugSettingsPreference = findPreference(PREF_DEBUG_SETTINGS);
- if (mDebugSettingsPreference != null) {
- final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN);
- debugSettingsIntent.setClassName(
- context.getPackageName(), DebugSettings.class.getName());
- mDebugSettingsPreference.setIntent(debugSettingsIntent);
- }
-
ensureConsistencyOfAutoCorrectionSettings();
final PreferenceGroup generalSettings =
@@ -150,6 +139,18 @@ public final class Settings extends InputMethodSettingsFragment
final PreferenceGroup miscSettings =
(PreferenceGroup) findPreference(PREF_MISC_SETTINGS);
+ mDebugSettingsPreference = findPreference(PREF_DEBUG_SETTINGS);
+ if (mDebugSettingsPreference != null) {
+ if (ProductionFlag.IS_INTERNAL) {
+ final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN);
+ debugSettingsIntent.setClassName(
+ context.getPackageName(), DebugSettingsActivity.class.getName());
+ mDebugSettingsPreference.setIntent(debugSettingsIntent);
+ } else {
+ miscSettings.removePreference(mDebugSettingsPreference);
+ }
+ }
+
final boolean showVoiceKeyOption = res.getBoolean(
R.bool.config_enable_show_voice_key_option);
if (!showVoiceKeyOption) {
@@ -218,24 +219,6 @@ public final class Settings extends InputMethodSettingsFragment
setPreferenceEnabled(gestureFloatingPreviewText, gestureInputEnabledByUser);
}
- final boolean showUsabilityStudyModeOption =
- res.getBoolean(R.bool.config_enable_usability_study_mode_option)
- || ProductionFlag.IS_EXPERIMENTAL || ENABLE_INTERNAL_SETTINGS;
- final Preference usabilityStudyPref = findPreference(PREF_USABILITY_STUDY_MODE);
- if (!showUsabilityStudyModeOption) {
- if (usabilityStudyPref != null) {
- miscSettings.removePreference(usabilityStudyPref);
- }
- }
- if (ProductionFlag.IS_EXPERIMENTAL) {
- if (usabilityStudyPref instanceof CheckBoxPreference) {
- CheckBoxPreference checkbox = (CheckBoxPreference)usabilityStudyPref;
- checkbox.setChecked(prefs.getBoolean(PREF_USABILITY_STUDY_MODE,
- ResearchLogger.DEFAULT_USABILITY_STUDY_MODE));
- checkbox.setSummary(R.string.settings_warning_researcher_mode);
- }
- }
-
mKeypressVibrationDurationSettingsPref =
(PreferenceScreen) findPreference(PREF_VIBRATION_DURATION_SETTINGS);
if (mKeypressVibrationDurationSettingsPref != null) {
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 9d8379a7a..5b8f1cfb4 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -410,7 +410,7 @@ public final class SettingsValues {
// Likewise
public static boolean getUsabilityStudyMode(final SharedPreferences prefs) {
// TODO: use mUsabilityStudyMode instead of reading it again here
- return prefs.getBoolean(Settings.PREF_USABILITY_STUDY_MODE, true);
+ return prefs.getBoolean(DebugSettings.PREF_USABILITY_STUDY_MODE, true);
}
public static long getLastUserHistoryWriteTime(final SharedPreferences prefs,
--
cgit v1.2.3-83-g751a
From 02a67200fc25d1be9dfbc35e3bb4b59bef28f386 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Fri, 21 Sep 2012 12:15:02 +0900
Subject: Fix gesture start detection algorithm
Bug: 7032858
Change-Id: I9f4d939fa87fdead4c5a5921338a16cd0a59b7ac
---
.../inputmethod/keyboard/PointerTracker.java | 10 +-
.../keyboard/internal/GestureStroke.java | 161 +++++++++++++++------
.../internal/GestureStrokeWithPreviewPoints.java | 15 +-
.../inputmethod/latin/BinaryDictionary.java | 2 +-
.../inputmethod/latin/UserHistoryDictionary.java | 2 +-
5 files changed, 127 insertions(+), 63 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 03d610a39..d4902ec28 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -688,7 +688,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
mIsDetectingGesture = true;
final int elapsedTimeFromFirstDown = (int)(eventTime - sGestureFirstDownTime);
mGestureStrokeWithPreviewPoints.addPoint(x, y, elapsedTimeFromFirstDown,
- false /* isHistorical */);
+ true /* isMajorEvent */);
}
private void onDownEventInternal(final int x, final int y, final long eventTime) {
@@ -724,10 +724,10 @@ public class PointerTracker implements PointerTrackerQueue.Element {
}
private void onGestureMoveEvent(final int x, final int y, final long eventTime,
- final boolean isHistorical, final Key key) {
+ final boolean isMajorEvent, final Key key) {
final int gestureTime = (int)(eventTime - sGestureFirstDownTime);
if (mIsDetectingGesture) {
- mGestureStrokeWithPreviewPoints.addPoint(x, y, gestureTime, isHistorical);
+ mGestureStrokeWithPreviewPoints.addPoint(x, y, gestureTime, isMajorEvent);
mayStartBatchInput();
if (sInGesture && key != null) {
updateBatchInput(eventTime);
@@ -752,7 +752,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
final int historicalY = (int)me.getHistoricalY(pointerIndex, h);
final long historicalTime = me.getHistoricalEventTime(h);
onGestureMoveEvent(historicalX, historicalY, historicalTime,
- true /* isHistorical */, null);
+ false /* isMajorEvent */, null);
}
}
@@ -767,7 +767,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
if (sShouldHandleGesture) {
// Register move event on gesture tracker.
- onGestureMoveEvent(x, y, eventTime, false /* isHistorical */, key);
+ onGestureMoveEvent(x, y, eventTime, true /* isMajorEvent */, key);
if (sInGesture) {
mIgnoreModifierKey = true;
mTimerProxy.cancelLongPressTimer();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
index f0be0ee94..73413f698 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
@@ -14,34 +14,45 @@
package com.android.inputmethod.keyboard.internal;
+import android.util.Log;
+
import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.ResizableIntArray;
public class GestureStroke {
+ private static final String TAG = GestureStroke.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
public static final int DEFAULT_CAPACITY = 128;
private final int mPointerId;
private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
- private float mLength;
private int mIncrementalRecognitionSize;
private int mLastIncrementalBatchSize;
- private long mLastPointTime;
- private int mLastPointX;
- private int mLastPointY;
-
- private int mMinGestureLength; // pixel
- private int mMinGestureSampleLength; // pixel
- private int mGestureRecognitionThreshold; // pixel / sec
+ private long mLastMajorEventTime;
+ private int mLastMajorEventX;
+ private int mLastMajorEventY;
+
+ private int mKeyWidth;
+ private int mStartGestureLengthThreshold; // pixel
+ private int mMinGestureSamplingLength; // pixel
+ private int mGestureRecognitionSpeedThreshold; // pixel / sec
+ private int mDetectFastMoveSpeedThreshold; // pixel /sec
+ private int mDetectFastMoveTime;
+ private int mDetectFastMoveX;
+ private int mDetectFastMoveY;
// TODO: Move some of these to resource.
- private static final float MIN_GESTURE_LENGTH_RATIO_TO_KEY_WIDTH = 0.75f;
- private static final int MIN_GESTURE_START_DURATION = 100; // msec
+ private static final float START_GESTURE_LENGTH_THRESHOLD_RATIO_TO_KEY_WIDTH = 0.75f;
+ private static final int START_GESTURE_DURATION_THRESHOLD = 70; // msec
private static final int MIN_GESTURE_RECOGNITION_TIME = 100; // msec
private static final float MIN_GESTURE_SAMPLING_RATIO_TO_KEY_WIDTH = 1.0f / 6.0f;
private static final float GESTURE_RECOGNITION_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH =
5.5f; // keyWidth / sec
+ private static final float DETECT_FAST_MOVE_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH =
+ 5.0f; // keyWidth / sec
private static final int MSEC_PER_SEC = 1000;
public static final boolean hasRecognitionTimePast(
@@ -54,64 +65,120 @@ public class GestureStroke {
}
public void setKeyboardGeometry(final int keyWidth) {
+ mKeyWidth = keyWidth;
// TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key?
- mMinGestureLength = (int)(keyWidth * MIN_GESTURE_LENGTH_RATIO_TO_KEY_WIDTH);
- mMinGestureSampleLength = (int)(keyWidth * MIN_GESTURE_SAMPLING_RATIO_TO_KEY_WIDTH);
- mGestureRecognitionThreshold =
+ mStartGestureLengthThreshold =
+ (int)(keyWidth * START_GESTURE_LENGTH_THRESHOLD_RATIO_TO_KEY_WIDTH);
+ mMinGestureSamplingLength = (int)(keyWidth * MIN_GESTURE_SAMPLING_RATIO_TO_KEY_WIDTH);
+ mGestureRecognitionSpeedThreshold =
(int)(keyWidth * GESTURE_RECOGNITION_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH);
+ mDetectFastMoveSpeedThreshold =
+ (int)(keyWidth * DETECT_FAST_MOVE_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH);
+ if (DEBUG) {
+ Log.d(TAG, "setKeyboardGeometry: keyWidth=" + keyWidth);
+ }
}
public boolean isStartOfAGesture() {
+ if (mDetectFastMoveTime == 0) {
+ return false;
+ }
final int size = mEventTimes.getLength();
- final int downDuration = (size > 0) ? mEventTimes.get(size - 1) : 0;
- return downDuration > MIN_GESTURE_START_DURATION && mLength > mMinGestureLength;
+ if (size <= 0) {
+ return false;
+ }
+ final int lastIndex = size - 1;
+ final int deltaTime = mEventTimes.get(lastIndex) - mDetectFastMoveTime;
+ final int deltaLength = getDistance(
+ mXCoordinates.get(lastIndex), mYCoordinates.get(lastIndex),
+ mDetectFastMoveX, mDetectFastMoveY);
+ final boolean isStartOfAGesture = deltaTime > START_GESTURE_DURATION_THRESHOLD
+ && deltaLength > mStartGestureLengthThreshold;
+ if (DEBUG) {
+ Log.d(TAG, "isStartOfAGesture: dT=" + deltaTime + " dL=" + deltaLength
+ + " points=" + size + (isStartOfAGesture ? " Detect start of a gesture" : ""));
+ }
+ return isStartOfAGesture;
}
public void reset() {
- mLength = 0;
mIncrementalRecognitionSize = 0;
mLastIncrementalBatchSize = 0;
- mLastPointTime = 0;
mEventTimes.setLength(0);
mXCoordinates.setLength(0);
mYCoordinates.setLength(0);
+ mLastMajorEventTime = 0;
+ mDetectFastMoveTime = 0;
+ }
+
+ private void appendPoint(final int x, final int y, final int time) {
+ mEventTimes.add(time);
+ mXCoordinates.add(x);
+ mYCoordinates.add(y);
}
- public void addPoint(final int x, final int y, final int time, final boolean isHistorical) {
- final boolean needsSampling;
+ private void updateMajorEvent(final int x, final int y, final int time) {
+ mLastMajorEventTime = time;
+ mLastMajorEventX = x;
+ mLastMajorEventY = y;
+ }
+
+ private int detectFastMove(final int x, final int y, final int time) {
final int size = mEventTimes.getLength();
- if (size == 0) {
- needsSampling = true;
- } else {
- final int lastIndex = size - 1;
- final int lastX = mXCoordinates.get(lastIndex);
- final int lastY = mYCoordinates.get(lastIndex);
- final float dist = getDistance(lastX, lastY, x, y);
- needsSampling = dist > mMinGestureSampleLength;
- mLength += dist;
+ final int lastIndex = size - 1;
+ final int lastX = mXCoordinates.get(lastIndex);
+ final int lastY = mYCoordinates.get(lastIndex);
+ final int dist = getDistance(lastX, lastY, x, y);
+ final int msecs = time - mEventTimes.get(lastIndex);
+ if (msecs > 0) {
+ final int pixels = getDistance(lastX, lastY, x, y);
+ final int pixelsPerSec = pixels * MSEC_PER_SEC;
+ if (DEBUG) {
+ final float speed = (float)pixelsPerSec / msecs / mKeyWidth;
+ Log.d(TAG, String.format("Speed=%.3f keyWidth/sec", speed));
+ }
+ // Equivalent to (pixels / msecs < mStartSpeedThreshold / MSEC_PER_SEC)
+ if (mDetectFastMoveTime == 0 && pixelsPerSec > mDetectFastMoveSpeedThreshold * msecs) {
+ if (DEBUG) {
+ Log.d(TAG, "Detect fast move: T=" + time + " points = " + size);
+ }
+ mDetectFastMoveTime = time;
+ mDetectFastMoveX = x;
+ mDetectFastMoveY = y;
+ }
}
- if (needsSampling) {
- mEventTimes.add(time);
- mXCoordinates.add(x);
- mYCoordinates.add(y);
+ return dist;
+ }
+
+ public void addPoint(final int x, final int y, final int time, final boolean isMajorEvent) {
+ final int size = mEventTimes.getLength();
+ if (size <= 0) {
+ // Down event
+ appendPoint(x, y, time);
+ updateMajorEvent(x, y, time);
+ } else {
+ final int dist = detectFastMove(x, y, time);
+ if (dist > mMinGestureSamplingLength) {
+ appendPoint(x, y, time);
+ }
}
- if (!isHistorical) {
+ if (isMajorEvent) {
updateIncrementalRecognitionSize(x, y, time);
+ updateMajorEvent(x, y, time);
}
}
private void updateIncrementalRecognitionSize(final int x, final int y, final int time) {
- final int msecs = (int)(time - mLastPointTime);
- if (msecs > 0) {
- final int pixels = (int)getDistance(mLastPointX, mLastPointY, x, y);
- // Equivalent to (pixels / msecs < mGestureRecognitionThreshold / MSEC_PER_SEC)
- if (pixels * MSEC_PER_SEC < mGestureRecognitionThreshold * msecs) {
- mIncrementalRecognitionSize = mEventTimes.getLength();
- }
+ final int msecs = (int)(time - mLastMajorEventTime);
+ if (msecs <= 0) {
+ return;
+ }
+ final int pixels = getDistance(mLastMajorEventX, mLastMajorEventY, x, y);
+ final int pixelsPerSec = pixels * MSEC_PER_SEC;
+ // Equivalent to (pixels / msecs < mGestureRecognitionThreshold / MSEC_PER_SEC)
+ if (pixelsPerSec < mGestureRecognitionSpeedThreshold * msecs) {
+ mIncrementalRecognitionSize = mEventTimes.getLength();
}
- mLastPointTime = time;
- mLastPointX = x;
- mLastPointY = y;
}
public void appendAllBatchPoints(final InputPointers out) {
@@ -132,11 +199,11 @@ public class GestureStroke {
mLastIncrementalBatchSize = size;
}
- private static float getDistance(final int x1, final int y1, final int x2, final int y2) {
- final float dx = x1 - x2;
- final float dy = y1 - y2;
+ private static int getDistance(final int x1, final int y1, final int x2, final int y2) {
+ final int dx = x1 - x2;
+ final int dy = y1 - y2;
// Note that, in recent versions of Android, FloatMath is actually slower than
// java.lang.Math due to the way the JIT optimizes java.lang.Math.
- return (float)Math.sqrt(dx * dx + dy * dy);
+ return (int)Math.sqrt(dx * dx + dy * dy);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
index ce3914076..3487b5018 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
@@ -65,21 +65,18 @@ public class GestureStrokeWithPreviewPoints extends GestureStroke {
private boolean needsSampling(final int x, final int y) {
final int dx = x - mLastX;
final int dy = y - mLastY;
- final boolean needsSampling = (dx * dx + dy * dy >= mMinPreviewSampleLengthSquare);
- if (needsSampling) {
- mLastX = x;
- mLastY = y;
- }
- return needsSampling;
+ return dx * dx + dy * dy >= mMinPreviewSampleLengthSquare;
}
@Override
- public void addPoint(final int x, final int y, final int time, final boolean isHistorical) {
- super.addPoint(x, y, time, isHistorical);
- if (mPreviewEventTimes.getLength() == 0 || isHistorical || needsSampling(x, y)) {
+ public void addPoint(final int x, final int y, final int time, final boolean isMajorEvent) {
+ super.addPoint(x, y, time, isMajorEvent);
+ if (isMajorEvent || needsSampling(x, y)) {
mPreviewEventTimes.add(time);
mPreviewXCoordinates.add(x);
mPreviewYCoordinates.add(y);
+ mLastX = x;
+ mLastY = y;
}
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index c3ae81f3a..9244f16b1 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -45,7 +45,7 @@ public class BinaryDictionary extends Dictionary {
public static final int MAX_WORDS = 18;
public static final int MAX_SPACES = 16;
- private static final String TAG = "BinaryDictionary";
+ private static final String TAG = BinaryDictionary.class.getSimpleName();
private static final int MAX_PREDICTIONS = 60;
private static final int MAX_RESULTS = Math.max(MAX_PREDICTIONS, MAX_WORDS);
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
index 683ee4f5c..e03af649c 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
@@ -42,7 +42,7 @@ import java.util.concurrent.locks.ReentrantLock;
* cancellation or manual picks. This allows the keyboard to adapt to the typist over time.
*/
public class UserHistoryDictionary extends ExpandableDictionary {
- private static final String TAG = "UserHistoryDictionary";
+ private static final String TAG = UserHistoryDictionary.class.getSimpleName();
public static final boolean DBG_SAVE_RESTORE = false;
public static final boolean DBG_STRESS_TEST = false;
public static final boolean DBG_ALWAYS_WRITE = false;
--
cgit v1.2.3-83-g751a
From 82d9deaaf252cd20f8918adbc7a4b9b8f2647c38 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Fri, 21 Sep 2012 21:21:58 +0900
Subject: Combine mHasParentAddress with mHasLinkedListNode into
mSupportsDynamicUpdate.
bug: 6669677
Change-Id: I82799af199358420f09ac34fc005091e202c5d3b
---
.../latin/makedict/BinaryDictIOUtils.java | 2 +-
.../latin/makedict/BinaryDictInputOutput.java | 35 +++++++++----------
.../inputmethod/latin/makedict/FormatSpec.java | 33 +++++-------------
.../latin/makedict/BinaryDictIOTests.java | 40 +++++++++-------------
4 files changed, 42 insertions(+), 68 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 397532933..ac0fb0ece 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -92,7 +92,7 @@ public class BinaryDictIOUtils {
}
if (p.mPosition == p.mNumOfCharGroup) {
- if (formatOptions.mHasLinkedListNode) {
+ if (formatOptions.mSupportsDynamicUpdate) {
final int forwardLinkAddress = buffer.readUnsignedInt24();
if (forwardLinkAddress != FormatSpec.NO_FORWARD_LINK_ADDRESS) {
// the node has a forward link.
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 7b8dc5cc5..4806bf9dc 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -376,7 +376,7 @@ public class BinaryDictInputOutput {
g.mCachedSize = groupSize;
size += groupSize;
}
- if (options.mHasLinkedListNode) {
+ if (options.mSupportsDynamicUpdate) {
size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
}
node.mCachedSize = size;
@@ -390,11 +390,11 @@ public class BinaryDictInputOutput {
}
/**
- * Helper method to check whether the CharGroup has a parent address.
+ * Helper method to check whether the dictionary can be updated dynamically.
*/
- public static boolean hasParentAddress(final FormatOptions options) {
- return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_PARENT_ADDRESS
- && options.mHasParentAddress;
+ public static boolean supportsDynamicUpdate(final FormatOptions options) {
+ return options.mVersion >= FormatSpec.FIRST_VERSION_WITH_DYNAMIC_UPDATE
+ && options.mSupportsDynamicUpdate;
}
/**
@@ -404,7 +404,7 @@ public class BinaryDictInputOutput {
* @param options file format options.
*/
private static int getGroupHeaderSize(final CharGroup group, final FormatOptions options) {
- if (hasParentAddress(options)) {
+ if (supportsDynamicUpdate(options)) {
return FormatSpec.GROUP_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
+ getGroupCharactersSize(group);
} else {
@@ -530,7 +530,7 @@ public class BinaryDictInputOutput {
group.mCachedSize = groupSize;
size += groupSize;
}
- if (formatOptions.mHasLinkedListNode) {
+ if (formatOptions.mSupportsDynamicUpdate) {
size += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
}
if (node.mCachedSize != size) {
@@ -559,7 +559,8 @@ public class BinaryDictInputOutput {
groupOffset += g.mCachedSize;
}
final int nodeSize = groupCountSize + groupOffset
- + (formatOptions.mHasLinkedListNode ? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0);
+ + (formatOptions.mSupportsDynamicUpdate
+ ? FormatSpec.FORWARD_LINK_ADDRESS_SIZE : 0);
if (nodeSize != n.mCachedSize) {
throw new RuntimeException("Bug : Stored and computed node size differ");
}
@@ -792,8 +793,7 @@ public class BinaryDictInputOutput {
return (options.mFrenchLigatureProcessing ? FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG : 0)
+ (options.mGermanUmlautProcessing ? FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG : 0)
+ (hasBigrams ? FormatSpec.CONTAINS_BIGRAMS_FLAG : 0)
- + (formatOptions.mHasParentAddress ? FormatSpec.HAS_PARENT_ADDRESS : 0)
- + (formatOptions.mHasLinkedListNode ? FormatSpec.HAS_LINKEDLIST_NODE : 0);
+ + (formatOptions.mSupportsDynamicUpdate ? FormatSpec.SUPPORTS_DYNAMIC_UPDATE : 0);
}
/**
@@ -857,7 +857,7 @@ public class BinaryDictInputOutput {
byte flags = makeCharGroupFlags(group, groupAddress, childrenOffset);
buffer[index++] = flags;
- if (hasParentAddress(formatOptions)) {
+ if (supportsDynamicUpdate(formatOptions)) {
if (parentAddress == FormatSpec.NO_PARENT_ADDRESS) {
// this node is the root node.
buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
@@ -927,7 +927,7 @@ public class BinaryDictInputOutput {
}
}
- if (formatOptions.mHasLinkedListNode) {
+ if (formatOptions.mSupportsDynamicUpdate) {
buffer[index] = buffer[index + 1] = buffer[index + 2]
= FormatSpec.NO_FORWARD_LINK_ADDRESS;
index += FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
@@ -1112,7 +1112,7 @@ public class BinaryDictInputOutput {
++addressPointer;
final int parentAddress;
- if (hasParentAddress(options)) {
+ if (supportsDynamicUpdate(options)) {
// read the parent address. (version 3)
parentAddress = -buffer.readUnsignedInt24();
addressPointer += 3;
@@ -1251,7 +1251,7 @@ public class BinaryDictInputOutput {
final String result;
final int originalPointer = buffer.position();
- if (hasParentAddress(formatOptions)) {
+ if (supportsDynamicUpdate(formatOptions)) {
result = getWordAtAddressWithParentAddress(buffer, headerSize, address, formatOptions);
} else {
result = getWordAtAddressWithoutParentAddress(buffer, headerSize, address,
@@ -1392,7 +1392,7 @@ public class BinaryDictInputOutput {
}
// reach the end of the array.
- if (options.mHasLinkedListNode) {
+ if (options.mSupportsDynamicUpdate) {
final int nextAddress = buffer.readUnsignedInt24();
if (nextAddress >= 0 && nextAddress < buffer.limit()) {
buffer.position(nextAddress);
@@ -1400,7 +1400,7 @@ public class BinaryDictInputOutput {
break;
}
}
- } while (options.mHasLinkedListNode &&
+ } while (options.mSupportsDynamicUpdate &&
buffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
final Node node = new Node(nodeContents);
@@ -1469,8 +1469,7 @@ public class BinaryDictInputOutput {
0 != (optionsFlags & FormatSpec.GERMAN_UMLAUT_PROCESSING_FLAG),
0 != (optionsFlags & FormatSpec.FRENCH_LIGATURE_PROCESSING_FLAG)),
new FormatOptions(version,
- 0 != (optionsFlags & FormatSpec.HAS_PARENT_ADDRESS),
- 0 != (optionsFlags & FormatSpec.HAS_LINKEDLIST_NODE)));
+ 0 != (optionsFlags & FormatSpec.SUPPORTS_DYNAMIC_UPDATE)));
return header;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index adc6037bb..63a61b46f 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -145,17 +145,14 @@ public final class FormatSpec {
static final int MAXIMUM_SUPPORTED_VERSION = 3;
static final int NOT_A_VERSION_NUMBER = -1;
static final int FIRST_VERSION_WITH_HEADER_SIZE = 2;
- static final int FIRST_VERSION_WITH_PARENT_ADDRESS = 3;
- static final int FIRST_VERSION_WITH_LINKEDLIST_NODE = 3;
+ static final int FIRST_VERSION_WITH_DYNAMIC_UPDATE = 3;
// These options need to be the same numeric values as the one in the native reading code.
static final int GERMAN_UMLAUT_PROCESSING_FLAG = 0x1;
// TODO: Make the native reading code read this variable.
- static final int HAS_PARENT_ADDRESS = 0x2;
+ static final int SUPPORTS_DYNAMIC_UPDATE = 0x2;
static final int FRENCH_LIGATURE_PROCESSING_FLAG = 0x4;
static final int CONTAINS_BIGRAMS_FLAG = 0x8;
- // TODO: Make the native reading code read this variable.
- static final int HAS_LINKEDLIST_NODE = 0x10;
// TODO: Make this value adaptative to content data, store it in the header, and
// use it in the reading code.
@@ -215,31 +212,17 @@ public final class FormatSpec {
*/
public static class FormatOptions {
public final int mVersion;
- public final boolean mHasParentAddress;
- public final boolean mHasLinkedListNode;
+ public final boolean mSupportsDynamicUpdate;
public FormatOptions(final int version) {
this(version, false);
}
- public FormatOptions(final int version, final boolean hasParentAddress) {
- this(version, hasParentAddress, false);
- }
- public FormatOptions(final int version, final boolean hasParentAddress,
- final boolean hasLinkedListNode) {
+ public FormatOptions(final int version, final boolean supportsDynamicUpdate) {
mVersion = version;
- if (version < FIRST_VERSION_WITH_PARENT_ADDRESS && hasParentAddress) {
- throw new RuntimeException("Parent addresses are only supported with versions "
- + FIRST_VERSION_WITH_PARENT_ADDRESS + " and ulterior.");
- }
- mHasParentAddress = hasParentAddress;
-
- if (version < FIRST_VERSION_WITH_LINKEDLIST_NODE && hasLinkedListNode) {
- throw new RuntimeException("Linked list nodes are only supported with versions "
- + FIRST_VERSION_WITH_LINKEDLIST_NODE + " and ulterior.");
- }
- if (!hasParentAddress && hasLinkedListNode) {
- throw new RuntimeException("Linked list nodes need parent addresses.");
+ if (version < FIRST_VERSION_WITH_DYNAMIC_UPDATE && supportsDynamicUpdate) {
+ throw new RuntimeException("Dynamic updates are only supported with versions "
+ + FIRST_VERSION_WITH_DYNAMIC_UPDATE + " and ulterior.");
}
- mHasLinkedListNode = hasLinkedListNode;
+ mSupportsDynamicUpdate = supportsDynamicUpdate;
}
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
index 539021f24..2f954318c 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOTests.java
@@ -65,13 +65,10 @@ public class BinaryDictIOTests extends AndroidTestCase {
CollectionUtils.newSparseArray();
private static final FormatSpec.FormatOptions VERSION2 = new FormatSpec.FormatOptions(2);
- private static final FormatSpec.FormatOptions VERSION3_WITHOUT_PARENTADDRESS =
- new FormatSpec.FormatOptions(3, false /* hasParentAddress */);
- private static final FormatSpec.FormatOptions VERSION3_WITH_PARENTADDRESS =
- new FormatSpec.FormatOptions(3, true /* hasParentAddress */);
- private static final FormatSpec.FormatOptions VERSION3_WITH_LINKEDLIST_NODE =
- new FormatSpec.FormatOptions(3, true /* hasParentAddress */,
- true /* hasLinkedListNode */);
+ private static final FormatSpec.FormatOptions VERSION3_WITHOUT_DYNAMIC_UPDATE =
+ new FormatSpec.FormatOptions(3, false /* supportsDynamicUpdate */);
+ private static final FormatSpec.FormatOptions VERSION3_WITH_DYNAMIC_UPDATE =
+ new FormatSpec.FormatOptions(3, true /* supportsDynamicUpdate */);
private static final String[] CHARACTERS = {
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
@@ -240,8 +237,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
String result = " : buffer type = "
+ ((bufferType == USE_BYTE_BUFFER) ? "byte buffer" : "byte array");
result += " : version = " + formatOptions.mVersion;
- return result + ", hasParentAddress = " + formatOptions.mHasParentAddress
- + ", hasLinkedListNode = " + formatOptions.mHasLinkedListNode;
+ return result + ", supportsDynamicUpdate = " + formatOptions.mSupportsDynamicUpdate;
}
// Tests for readDictionaryBinary and writeDictionaryBinary
@@ -308,9 +304,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List results = CollectionUtils.newArrayList();
runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION2);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_PARENTADDRESS);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_PARENTADDRESS);
- runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_LINKEDLIST_NODE);
+ runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE);
+ runReadAndWriteTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE);
for (final String result : results) {
Log.d(TAG, result);
@@ -321,9 +316,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List results = CollectionUtils.newArrayList();
runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION2);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_PARENTADDRESS);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_PARENTADDRESS);
- runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_LINKEDLIST_NODE);
+ runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE);
+ runReadAndWriteTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE);
for (final String result : results) {
Log.d(TAG, result);
@@ -455,9 +449,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List results = CollectionUtils.newArrayList();
runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION2);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_PARENTADDRESS);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_PARENTADDRESS);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_LINKEDLIST_NODE);
+ runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITHOUT_DYNAMIC_UPDATE);
+ runReadUnigramsAndBigramsTests(results, USE_BYTE_BUFFER, VERSION3_WITH_DYNAMIC_UPDATE);
for (final String result : results) {
Log.d(TAG, result);
@@ -468,9 +461,8 @@ public class BinaryDictIOTests extends AndroidTestCase {
final List results = CollectionUtils.newArrayList();
runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION2);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_PARENTADDRESS);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_PARENTADDRESS);
- runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_LINKEDLIST_NODE);
+ runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITHOUT_DYNAMIC_UPDATE);
+ runReadUnigramsAndBigramsTests(results, USE_BYTE_ARRAY, VERSION3_WITH_DYNAMIC_UPDATE);
for (final String result : results) {
Log.d(TAG, result);
@@ -528,7 +520,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
new FusionDictionary.DictionaryOptions(
new HashMap(), false, false));
addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
- timeWritingDictToFile(file, dict, VERSION3_WITH_LINKEDLIST_NODE);
+ timeWritingDictToFile(file, dict, VERSION3_WITH_DYNAMIC_UPDATE);
final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY);
@@ -569,7 +561,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
public void testDeleteWord() {
File file = null;
try {
- file = File.createTempFile("testGetTerminalPosition", ".dict");
+ file = File.createTempFile("testDeleteWord", ".dict");
} catch (IOException e) {
// do nothing
}
@@ -579,7 +571,7 @@ public class BinaryDictIOTests extends AndroidTestCase {
new FusionDictionary.DictionaryOptions(
new HashMap(), false, false));
addUnigrams(sWords.size(), dict, sWords, null /* shortcutMap */);
- timeWritingDictToFile(file, dict, VERSION3_WITH_LINKEDLIST_NODE);
+ timeWritingDictToFile(file, dict, VERSION3_WITH_DYNAMIC_UPDATE);
final FusionDictionaryBufferInterface buffer = getBuffer(file, USE_BYTE_ARRAY);
--
cgit v1.2.3-83-g751a
From fff8613df04af17bf56db866075b220d1ef0fbe8 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 24 Sep 2012 14:40:23 +0900
Subject: Fix a race condition with shift
Bug: 7062092
Change-Id: Ie1984673e9ffc9291d9650ec38ce99031ad93585
---
java/src/com/android/inputmethod/latin/LatinIME.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 9252b0980..b77eef412 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -856,7 +856,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: the following is probably better done in resetEntireInputState().
// it should only happen when the cursor moved, and the very purpose of the
// test below is to narrow down whether this happened or not. Likewise with
- // the call to postUpdateShiftState.
+ // the call to updateShiftState.
// We set this to NONE because after a cursor move, we don't want the space
// state-related special processing to kick in.
mSpaceState = SPACE_STATE_NONE;
@@ -865,7 +865,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
resetEntireInputState(newSelStart);
}
- mHandler.postUpdateShiftState();
+ mKeyboardSwitcher.updateShiftState();
}
mExpectingUpdateSelection = false;
// TODO: Decide to call restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() or not
@@ -1551,7 +1551,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void handleBackspace(final int spaceState) {
- // In many cases, we may have to put the keyboard in auto-shift state again.
+ // In many cases, we may have to put the keyboard in auto-shift state again. However
+ // we want to wait a few milliseconds before doing it to avoid the keyboard flashing
+ // during key repeat.
mHandler.postUpdateShiftState();
if (mWordComposer.isComposingWord()) {
@@ -1791,7 +1793,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
Utils.Stats.onSeparator((char)primaryCode, x, y);
}
- mHandler.postUpdateShiftState();
+ mKeyboardSwitcher.updateShiftState();
return didAutoCorrect;
}
--
cgit v1.2.3-83-g751a
From 6efe788494195fb8a57a2317cfa35e01ae7fda13 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 24 Sep 2012 17:27:03 +0900
Subject: Set punctuation suggestions at start if activated
Bug: 7218468
Change-Id: I9f8c1f13dc26cedb95b65279a34a825021dfa72a
---
java/src/com/android/inputmethod/latin/LatinIME.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b77eef412..45ecfd2e7 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -715,7 +715,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSpaceState = SPACE_STATE_NONE;
if (mSuggestionStripView != null) {
- mSuggestionStripView.clear();
+ // This will set the punctuation suggestions if next word suggestion is off;
+ // otherwise it will clear the suggestion strip.
+ setPunctuationSuggestions();
}
}
--
cgit v1.2.3-83-g751a
From 72c5d328882976a0b4ae8b01a872ff5ae4d10547 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 24 Sep 2012 19:33:42 +0900
Subject: Fix a bug where the cursor pos wouldn't be tracked correctly
This would cause
Bug: 7208199
Change-Id: I8474985bfe349e1530b27bc98842937627bbe4e0
---
java/src/com/android/inputmethod/latin/LatinIME.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b77eef412..00608c5c5 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -719,7 +719,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- mConnection.resetCachesUponCursorMove(mLastSelectionStart);
+ mConnection.resetCachesUponCursorMove(editorInfo.initialSelStart);
if (isDifferentTextField) {
mainKeyboardView.closing();
--
cgit v1.2.3-83-g751a
From 6a58bb7ac95e804f87c4e88b5eb970d28210518e Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 24 Sep 2012 16:15:20 +0900
Subject: Add suggestion span upon starting a gesture.
Bug: 7196761
Change-Id: If60cb809b205159ced1887f94b7caf9775fcf3bb
---
java/src/com/android/inputmethod/latin/LatinIME.java | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b77eef412..5712d3b05 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -862,6 +862,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSpaceState = SPACE_STATE_NONE;
if ((!mWordComposer.isComposingWord()) || selectionChanged || noComposingSpan) {
+ // If we are composing a word and moving the cursor, we would want to set a
+ // suggestion span for recorrection to work correctly. Unfortunately, that
+ // would involve the keyboard committing some new text, which would move the
+ // cursor back to where it was. Latin IME could then fix the position of the cursor
+ // again, but the asynchronous nature of the calls results in this wreaking havoc
+ // with selection on double tap and the like.
+ // Another option would be to send suggestions each time we set the composing
+ // text, but that is probably too expensive to do, so we decided to leave things
+ // as is.
resetEntireInputState(newSelStart);
}
@@ -1087,11 +1096,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (!mWordComposer.isComposingWord()) return;
final CharSequence typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) {
- mConnection.commitText(typedWord, 1);
- final CharSequence prevWord = addToUserHistoryDictionary(typedWord);
- mLastComposedWord = mWordComposer.commitWord(
- LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, typedWord.toString(),
- separatorString, prevWord);
+ commitChosenWord(typedWord, LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD,
+ separatorString);
}
}
--
cgit v1.2.3-83-g751a
From 8ec0064c49e80945dbe1bb31129eb890478b7e06 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Thu, 20 Sep 2012 16:21:40 +0900
Subject: Make children addresses and parent addresses use signed addresses.
Signed addresses are used only in version 3 with dynamic update.
bug: 6669677
Change-Id: Iadaeab199b5019d2330b4573c24da74d64f0945e
---
.../latin/makedict/BinaryDictInputOutput.java | 212 +++++++++++++++------
.../inputmethod/latin/makedict/FormatSpec.java | 21 +-
2 files changed, 166 insertions(+), 67 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 4806bf9dc..d4a4d7cda 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -36,7 +36,6 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.Stack;
import java.util.TreeMap;
/**
@@ -412,6 +411,10 @@ public class BinaryDictInputOutput {
}
}
+ private static final int UINT8_MAX = 0xFF;
+ private static final int UINT16_MAX = 0xFFFF;
+ private static final int UINT24_MAX = 0xFFFFFF;
+
/**
* Compute the size, in bytes, that an address will occupy.
*
@@ -423,17 +426,25 @@ public class BinaryDictInputOutput {
* @return the byte size.
*/
private static int getByteSize(final int address) {
- assert(address < 0x1000000);
+ assert(address <= UINT24_MAX);
if (!hasChildrenAddress(address)) {
return 0;
- } else if (Math.abs(address) < 0x100) {
+ } else if (Math.abs(address) <= UINT8_MAX) {
return 1;
- } else if (Math.abs(address) < 0x10000) {
+ } else if (Math.abs(address) <= UINT16_MAX) {
return 2;
} else {
return 3;
}
}
+
+ private static final int SINT8_MAX = 0x7F;
+ private static final int SINT16_MAX = 0x7FFF;
+ private static final int SINT24_MAX = 0x7FFFFF;
+ private static final int MSB8 = 0x80;
+ private static final int MSB16 = 0x8000;
+ private static final int MSB24 = 0x800000;
+
// End utility methods.
// This method is responsible for finding a nice ordering of the nodes that favors run-time
@@ -509,13 +520,19 @@ public class BinaryDictInputOutput {
}
int groupSize = getGroupHeaderSize(group, formatOptions);
if (group.isTerminal()) groupSize += FormatSpec.GROUP_FREQUENCY_SIZE;
- if (null != group.mChildren) {
+ if (null == group.mChildren && formatOptions.mSupportsDynamicUpdate) {
+ groupSize += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
+ } else if (null != group.mChildren) {
final int offsetBasePoint = groupSize + node.mCachedAddress + size;
final int offset = group.mChildren.mCachedAddress - offsetBasePoint;
// assign my address to children's parent address
group.mChildren.mCachedParentAddress = group.mCachedAddress
- group.mChildren.mCachedAddress;
- groupSize += getByteSize(offset);
+ if (formatOptions.mSupportsDynamicUpdate) {
+ groupSize += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
+ } else {
+ groupSize += getByteSize(offset);
+ }
}
groupSize += getShortcutListSize(group.mShortcutTargets);
if (null != group.mBigrams) {
@@ -669,27 +686,52 @@ public class BinaryDictInputOutput {
}
}
+ /**
+ * Helper method to write a variable-size signed address to a file.
+ *
+ * @param buffer the buffer to write to.
+ * @param index the index in the buffer to write the address to.
+ * @param address the address to write.
+ * @return the size in bytes the address actually took.
+ */
+ private static int writeVariableSignedAddress(final byte[] buffer, int index,
+ final int address) {
+ if (!hasChildrenAddress(address)) {
+ buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
+ } else {
+ final int absAddress = Math.abs(address);
+ buffer[index++] = (byte)((address < 0 ? MSB8 : 0) | (0xFF & (absAddress >> 16)));
+ buffer[index++] = (byte)(0xFF & (absAddress >> 8));
+ buffer[index++] = (byte)(0xFF & absAddress);
+ }
+ return 3;
+ }
+
private static byte makeCharGroupFlags(final CharGroup group, final int groupAddress,
- final int childrenOffset) {
+ final int childrenOffset, final FormatOptions formatOptions) {
byte flags = 0;
if (group.mChars.length > 1) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS;
if (group.mFrequency >= 0) {
flags |= FormatSpec.FLAG_IS_TERMINAL;
}
if (null != group.mChildren) {
- switch (getByteSize(childrenOffset)) {
- case 1:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE;
- break;
- case 2:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES;
- break;
- case 3:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
- break;
- default:
- throw new RuntimeException("Node with a strange address");
- }
+ final int byteSize = formatOptions.mSupportsDynamicUpdate
+ ? FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE : getByteSize(childrenOffset);
+ switch (byteSize) {
+ case 1:
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE;
+ break;
+ case 2:
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES;
+ break;
+ case 3:
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
+ break;
+ default:
+ throw new RuntimeException("Node with a strange address");
+ }
+ } else if (formatOptions.mSupportsDynamicUpdate) {
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
}
if (null != group.mShortcutTargets) {
if (DBG && 0 == group.mShortcutTargets.size()) {
@@ -808,6 +850,25 @@ public class BinaryDictInputOutput {
+ (frequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY);
}
+ private static final int writeParentAddress(final byte[] buffer, final int index,
+ final int address, final FormatOptions formatOptions) {
+ if (supportsDynamicUpdate(formatOptions)) {
+ if (address == FormatSpec.NO_PARENT_ADDRESS) {
+ buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
+ } else {
+ final int absAddress = Math.abs(address);
+ assert(absAddress <= SINT24_MAX);
+ buffer[index] = (byte)((address < 0 ? MSB8 : 0)
+ | ((absAddress >> 16) & 0xFF));
+ buffer[index + 1] = (byte)((absAddress >> 8) & 0xFF);
+ buffer[index + 2] = (byte)(absAddress & 0xFF);
+ }
+ return index + 3;
+ } else {
+ return index;
+ }
+ }
+
/**
* Write a node to memory. The node is expected to have its final position cached.
*
@@ -854,22 +915,15 @@ public class BinaryDictInputOutput {
final int childrenOffset = null == group.mChildren
? FormatSpec.NO_CHILDREN_ADDRESS
: group.mChildren.mCachedAddress - groupAddress;
- byte flags = makeCharGroupFlags(group, groupAddress, childrenOffset);
+ byte flags = makeCharGroupFlags(group, groupAddress, childrenOffset, formatOptions);
buffer[index++] = flags;
- if (supportsDynamicUpdate(formatOptions)) {
- if (parentAddress == FormatSpec.NO_PARENT_ADDRESS) {
- // this node is the root node.
- buffer[index] = buffer[index + 1] = buffer[index + 2] = 0;
- } else {
- // write parent address. (version 3)
- final int actualParentAddress = Math.abs(parentAddress
- + (node.mCachedAddress - group.mCachedAddress));
- buffer[index] = (byte)((actualParentAddress >> 16) & 0xFF);
- buffer[index + 1] = (byte)((actualParentAddress >> 8) & 0xFF);
- buffer[index + 2] = (byte)(actualParentAddress & 0xFF);
- }
- index += 3;
+ if (parentAddress == FormatSpec.NO_PARENT_ADDRESS) {
+ index = writeParentAddress(buffer, index, parentAddress, formatOptions);
+ } else {
+ index = writeParentAddress(buffer, index,
+ parentAddress + (node.mCachedAddress - group.mCachedAddress),
+ formatOptions);
}
index = CharEncoding.writeCharArray(group.mChars, buffer, index);
@@ -879,7 +933,13 @@ public class BinaryDictInputOutput {
if (group.mFrequency >= 0) {
buffer[index++] = (byte) group.mFrequency;
}
- final int shift = writeVariableAddress(buffer, index, childrenOffset);
+
+ final int shift;
+ if (formatOptions.mSupportsDynamicUpdate) {
+ shift = writeVariableSignedAddress(buffer, index, childrenOffset);
+ } else {
+ shift = writeVariableAddress(buffer, index, childrenOffset);
+ }
index += shift;
groupAddress += shift;
@@ -1104,6 +1164,58 @@ public class BinaryDictInputOutput {
// Input methods: Read a binary dictionary to memory.
// readDictionaryBinary is the public entry point for them.
+ private static int getChildrenAddressSize(final int optionFlags,
+ final FormatOptions formatOptions) {
+ if (formatOptions.mSupportsDynamicUpdate) return FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
+ switch (optionFlags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE:
+ return 1;
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES:
+ return 2;
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES:
+ return 3;
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_NOADDRESS:
+ default:
+ return 0;
+ }
+ }
+
+ private static int readChildrenAddress(final FusionDictionaryBufferInterface buffer,
+ final int optionFlags, final FormatOptions options) {
+ if (options.mSupportsDynamicUpdate) {
+ final int address = buffer.readUnsignedInt24();
+ if (address == 0) return FormatSpec.NO_CHILDREN_ADDRESS;
+ if ((address & MSB24) != 0) {
+ return -(address & SINT24_MAX);
+ } else {
+ return address;
+ }
+ }
+ int address;
+ switch (optionFlags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE:
+ return buffer.readUnsignedByte();
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES:
+ return buffer.readUnsignedShort();
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES:
+ return buffer.readUnsignedInt24();
+ case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_NOADDRESS:
+ default:
+ return FormatSpec.NO_CHILDREN_ADDRESS;
+ }
+ }
+
+ private static int readParentAddress(final FusionDictionaryBufferInterface buffer,
+ final FormatOptions formatOptions) {
+ if (supportsDynamicUpdate(formatOptions)) {
+ final int parentAddress = buffer.readUnsignedInt24();
+ final int sign = ((parentAddress & MSB24) != 0) ? -1 : 1;
+ return sign * (parentAddress & SINT24_MAX);
+ } else {
+ return FormatSpec.NO_PARENT_ADDRESS;
+ }
+ }
+
private static final int[] CHARACTER_BUFFER = new int[FormatSpec.MAX_WORD_LENGTH];
public static CharGroupInfo readCharGroup(final FusionDictionaryBufferInterface buffer,
final int originalGroupAddress, final FormatOptions options) {
@@ -1111,13 +1223,9 @@ public class BinaryDictInputOutput {
final int flags = buffer.readUnsignedByte();
++addressPointer;
- final int parentAddress;
+ final int parentAddress = readParentAddress(buffer, options);
if (supportsDynamicUpdate(options)) {
- // read the parent address. (version 3)
- parentAddress = -buffer.readUnsignedInt24();
addressPointer += 3;
- } else {
- parentAddress = FormatSpec.NO_PARENT_ADDRESS;
}
final int characters[];
@@ -1146,25 +1254,11 @@ public class BinaryDictInputOutput {
} else {
frequency = CharGroup.NOT_A_TERMINAL;
}
- int childrenAddress = addressPointer;
- switch (flags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) {
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE:
- childrenAddress += buffer.readUnsignedByte();
- addressPointer += 1;
- break;
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES:
- childrenAddress += buffer.readUnsignedShort();
- addressPointer += 2;
- break;
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES:
- childrenAddress += buffer.readUnsignedInt24();
- addressPointer += 3;
- break;
- case FormatSpec.FLAG_GROUP_ADDRESS_TYPE_NOADDRESS:
- default:
- childrenAddress = FormatSpec.NO_CHILDREN_ADDRESS;
- break;
+ int childrenAddress = readChildrenAddress(buffer, flags, options);
+ if (childrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ childrenAddress += addressPointer;
}
+ addressPointer += getChildrenAddressSize(flags, options);
ArrayList shortcutTargets = null;
if (0 != (flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)) {
final int pointerBefore = buffer.position();
@@ -1250,6 +1344,7 @@ public class BinaryDictInputOutput {
final String result;
final int originalPointer = buffer.position();
+ buffer.position(address);
if (supportsDynamicUpdate(formatOptions)) {
result = getWordAtAddressWithParentAddress(buffer, headerSize, address, formatOptions);
@@ -1279,7 +1374,6 @@ public class BinaryDictInputOutput {
sGetWordBuffer[index--] =
currentInfo.mCharacters[currentInfo.mCharacters.length - i - 1];
}
-
if (currentInfo.mParentAddress == FormatSpec.NO_PARENT_ADDRESS) break;
currentAddress = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 63a61b46f..cab0661f6 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -42,11 +42,13 @@ public final class FormatSpec {
* ps
*
* f |
- * o | IF HAS_LINKEDLIST_NODE (defined in the file header)
+ * o | IF SUPPORTS_DYNAMIC_UPDATE (defined in the file header)
* r | forward link address, 3byte
- * w | the address must be positive.
- * a |
- * rdlinkaddress
+ * w | 1 byte = bbbbbbbb match
+ * a | case 1xxxxxxx => -((xxxxxxx << 16) + (next byte << 8) + next byte)
+ * r | otherwise => (xxxxxxx << 16) + (next byte << 8) + next byte
+ * d |
+ * linkaddress
*/
/* Node(CharGroup) layout is as follows:
@@ -63,11 +65,13 @@ public final class FormatSpec {
* | is blacklisted ? 1 bit, 1 = yes, 0 = no : FLAG_IS_BLACKLISTED
*
* p |
- * a | IF HAS_PARENT_ADDRESS (defined in the file header)
+ * a | IF SUPPORTS_DYNAMIC_UPDATE (defined in the file header)
* r | parent address, 3byte
- * e | the address must be negative, so the absolute value of the address is stored.
- * n |
- * taddress
+ * e | 1 byte = bbbbbbbb match
+ * n | case 1xxxxxxx => -((0xxxxxxx << 16) + (next byte << 8) + next byte)
+ * t | otherwise => (bbbbbbbb << 16) + (next byte << 8) + next byte
+ * a |
+ * ddress
*
* c | IF FLAG_HAS_MULTIPLE_CHARS
* h | char, char, char, char n * (1 or 3 bytes) : use CharGroupInfo for i/o helpers
@@ -206,6 +210,7 @@ public final class FormatSpec {
// This option needs to be the same numeric value as the one in binary_format.h.
static final int NOT_VALID_WORD = -99;
+ static final int SIGNED_CHILDREN_ADDRESS_SIZE = 3;
/**
* Options about file format.
--
cgit v1.2.3-83-g751a
From 93d7c6233fb6b867d51a9eeb54b951fe3a377ea8 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Tue, 25 Sep 2012 16:14:16 +0900
Subject: Make getTerminalPosition read linked-list nodes.
bug: 6669677
Change-Id: I599d276f430efe23d402695c325e23906b7705b3
---
.../latin/makedict/BinaryDictIOUtils.java | 80 +++++++++++++---------
1 file changed, 48 insertions(+), 32 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index ac0fb0ece..19da5124a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -157,47 +157,63 @@ public class BinaryDictIOUtils {
final int wordLen = word.codePointCount(0, word.length());
for (int depth = 0; depth < Constants.Dictionary.MAX_WORD_LENGTH; ++depth) {
if (wordPos >= wordLen) return FormatSpec.NOT_VALID_WORD;
- int groupOffset = buffer.position() - header.mHeaderSize;
- final int charGroupCount = BinaryDictInputOutput.readCharGroupCount(buffer);
- groupOffset += BinaryDictInputOutput.getGroupCountSize(charGroupCount);
-
- for (int i = 0; i < charGroupCount; ++i) {
- final int charGroupPos = buffer.position();
- final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
- buffer.position(), header.mFormatOptions);
- boolean same = true;
- for (int p = 0, j = word.offsetByCodePoints(0, wordPos);
- p < currentInfo.mCharacters.length;
- ++p, j = word.offsetByCodePoints(j, 1)) {
- if (wordPos + p >= wordLen
- || word.codePointAt(j) != currentInfo.mCharacters[p]) {
- same = false;
- break;
+
+ do {
+ int groupOffset = buffer.position() - header.mHeaderSize;
+ final int charGroupCount = BinaryDictInputOutput.readCharGroupCount(buffer);
+ groupOffset += BinaryDictInputOutput.getGroupCountSize(charGroupCount);
+
+ boolean foundNextCharGroup = false;
+ for (int i = 0; i < charGroupCount; ++i) {
+ final int charGroupPos = buffer.position();
+ final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
+ buffer.position(), header.mFormatOptions);
+ boolean same = true;
+ for (int p = 0, j = word.offsetByCodePoints(0, wordPos);
+ p < currentInfo.mCharacters.length;
+ ++p, j = word.offsetByCodePoints(j, 1)) {
+ if (wordPos + p >= wordLen
+ || word.codePointAt(j) != currentInfo.mCharacters[p]) {
+ same = false;
+ break;
+ }
}
- }
- if (same) {
- if (wordPos + currentInfo.mCharacters.length == wordLen) {
- if (currentInfo.mFrequency == CharGroup.NOT_A_TERMINAL) {
+ if (same) {
+ // found the group matches the word.
+ if (wordPos + currentInfo.mCharacters.length == wordLen) {
+ if (currentInfo.mFrequency == CharGroup.NOT_A_TERMINAL) {
+ return FormatSpec.NOT_VALID_WORD;
+ } else {
+ return charGroupPos;
+ }
+ }
+ wordPos += currentInfo.mCharacters.length;
+ if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
return FormatSpec.NOT_VALID_WORD;
- } else {
- return charGroupPos;
}
+ foundNextCharGroup = true;
+ buffer.position(currentInfo.mChildrenAddress);
+ break;
}
- wordPos += currentInfo.mCharacters.length;
- if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
- return FormatSpec.NOT_VALID_WORD;
- }
- buffer.position(currentInfo.mChildrenAddress);
- break;
+ groupOffset = currentInfo.mEndAddress;
}
- groupOffset = currentInfo.mEndAddress;
- // not found
- if (i >= charGroupCount - 1) {
+ // If we found the next char group, it is under the file pointer.
+ // But if not, we are at the end of this node so we expect to have
+ // a forward link address that we need to consult and possibly resume
+ // search on the next node in the linked list.
+ if (foundNextCharGroup) break;
+ if (!header.mFormatOptions.mSupportsDynamicUpdate) {
return FormatSpec.NOT_VALID_WORD;
}
- }
+
+ final int forwardLinkAddress = buffer.readUnsignedInt24();
+ if (forwardLinkAddress == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ return FormatSpec.NOT_VALID_WORD;
+ }
+ buffer.position(forwardLinkAddress);
+ } while(true);
}
return FormatSpec.NOT_VALID_WORD;
}
--
cgit v1.2.3-83-g751a
From a161bdac885fc8e5f0063d33b055b0a6ecdefbdb Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Tue, 25 Sep 2012 17:52:31 +0900
Subject: add capacity to FusionDictionaryBufferInterface.
bug: 6669677
Change-Id: I4627093811a19c46ce13fe351d1db63cbd78cf4a
---
java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java | 5 +++++
.../android/inputmethod/latin/makedict/BinaryDictInputOutput.java | 6 ++++++
2 files changed, 11 insertions(+)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
index 4a3d11aa1..05255a6b3 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
@@ -100,6 +100,11 @@ public class UserHistoryDictIOUtils {
@Override
public int limit() {
+ return mBuffer.length - 1;
+ }
+
+ @Override
+ public int capacity() {
return mBuffer.length;
}
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index d4a4d7cda..f9339de08 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -63,6 +63,7 @@ public class BinaryDictInputOutput {
public void position(int newPosition);
public void put(final byte b);
public int limit();
+ public int capacity();
}
public static final class ByteBufferWrapper implements FusionDictionaryBufferInterface {
@@ -112,6 +113,11 @@ public class BinaryDictInputOutput {
public int limit() {
return mBuffer.limit();
}
+
+ @Override
+ public int capacity() {
+ return mBuffer.capacity();
+ }
}
/**
--
cgit v1.2.3-83-g751a
From 2ee70804e92b17016a2f042c4f6b0e94b5d23e88 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Tue, 25 Sep 2012 20:48:25 +0900
Subject: Add moved char groups.
bug: 6669677
Change-Id: I372f841044fe8e076a50a80ac10b715e5f8fd4eb
---
.../latin/makedict/BinaryDictIOUtils.java | 11 +++++++++--
.../latin/makedict/BinaryDictInputOutput.java | 23 ++++++++++++++++++++--
.../inputmethod/latin/makedict/FormatSpec.java | 20 ++++++++++++-------
3 files changed, 43 insertions(+), 11 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 19da5124a..e2c1254ce 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -85,7 +85,10 @@ public class BinaryDictIOUtils {
}
p.mPosition++;
- if (info.mFrequency != FusionDictionary.CharGroup.NOT_A_TERMINAL) { // found word
+ final boolean isMovedGroup = BinaryDictInputOutput.isMovedGroup(info.mFlags,
+ formatOptions);
+ if (!isMovedGroup
+ && info.mFrequency != FusionDictionary.CharGroup.NOT_A_TERMINAL) {// found word
words.put(info.mOriginalAddress, new String(pushedChars, 0, index));
frequencies.put(info.mOriginalAddress, info.mFrequency);
if (info.mBigrams != null) bigrams.put(info.mOriginalAddress, info.mBigrams);
@@ -109,7 +112,7 @@ public class BinaryDictIOUtils {
p.mAddress = buffer.position();
}
- if (BinaryDictInputOutput.hasChildrenAddress(info.mChildrenAddress)) {
+ if (!isMovedGroup && BinaryDictInputOutput.hasChildrenAddress(info.mChildrenAddress)) {
Position childrenPos = new Position(info.mChildrenAddress + headerSize, index);
stack.push(childrenPos);
}
@@ -168,6 +171,10 @@ public class BinaryDictIOUtils {
final int charGroupPos = buffer.position();
final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
buffer.position(), header.mFormatOptions);
+ if (BinaryDictInputOutput.isMovedGroup(currentInfo.mFlags,
+ header.mFormatOptions)) {
+ continue;
+ }
boolean same = true;
for (int p = 0, j = word.offsetByCodePoints(0, wordPos);
p < currentInfo.mCharacters.length;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index f9339de08..9fc694218 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -53,6 +53,7 @@ public class BinaryDictInputOutput {
// If the number of passes exceeds this number, makedict bails with an exception on
// suspicion that a bug might be causing an infinite loop.
private static final int MAX_PASSES = 24;
+ private static final int MAX_JUMPS = 12;
public interface FusionDictionaryBufferInterface {
public int readUnsignedByte();
@@ -394,6 +395,13 @@ public class BinaryDictInputOutput {
return FormatSpec.NO_CHILDREN_ADDRESS != address;
}
+ /**
+ * Helper method to check whether the group is moved.
+ */
+ public static boolean isMovedGroup(final int flags, final FormatOptions options) {
+ return options.mSupportsDynamicUpdate && ((flags & FormatSpec.FLAG_IS_MOVED) == 1);
+ }
+
/**
* Helper method to check whether the dictionary can be updated dynamically.
*/
@@ -1374,8 +1382,18 @@ public class BinaryDictInputOutput {
int index = FormatSpec.MAX_WORD_LENGTH - 1;
// the length of the path from the root to the leaf is limited by MAX_WORD_LENGTH
for (int count = 0; count < FormatSpec.MAX_WORD_LENGTH; ++count) {
- buffer.position(currentAddress + headerSize);
- final CharGroupInfo currentInfo = readCharGroup(buffer, currentAddress, options);
+ CharGroupInfo currentInfo;
+ int loopCounter = 0;
+ do {
+ buffer.position(currentAddress + headerSize);
+ currentInfo = readCharGroup(buffer, currentAddress, options);
+ if (isMovedGroup(currentInfo.mFlags, options)) {
+ currentAddress = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
+ }
+ if (DBG && loopCounter++ > MAX_JUMPS) {
+ MakedictLog.d("Too many jumps - probably a bug");
+ }
+ } while (isMovedGroup(currentInfo.mFlags, options));
for (int i = 0; i < currentInfo.mCharacters.length; ++i) {
sGetWordBuffer[index--] =
currentInfo.mCharacters[currentInfo.mCharacters.length - i - 1];
@@ -1457,6 +1475,7 @@ public class BinaryDictInputOutput {
int groupOffset = nodeHeadPosition + getGroupCountSize(count);
for (int i = count; i > 0; --i) { // Scan the array of CharGroup.
CharGroupInfo info = readCharGroup(buffer, groupOffset, options);
+ if (isMovedGroup(info.mFlags, options)) continue;
ArrayList shortcutTargets = info.mShortcutTargets;
ArrayList bigrams = null;
if (null != info.mBigrams) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index cab0661f6..35311f0c2 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -52,13 +52,18 @@ public final class FormatSpec {
*/
/* Node(CharGroup) layout is as follows:
- * | addressType xx : mask with MASK_GROUP_ADDRESS_TYPE
- * 2 bits, 00 = no children : FLAG_GROUP_ADDRESS_TYPE_NOADDRESS
- * f | 01 = 1 byte : FLAG_GROUP_ADDRESS_TYPE_ONEBYTE
- * l | 10 = 2 bytes : FLAG_GROUP_ADDRESS_TYPE_TWOBYTES
- * a | 11 = 3 bytes : FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
- * g | has several chars ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_MULTIPLE_CHARS
- * s | has a terminal ? 1 bit, 1 = yes, 0 = no : FLAG_IS_TERMINAL
+ * | IF !SUPPORTS_DYNAMIC_UPDATE
+ * | addressType xx : mask with MASK_GROUP_ADDRESS_TYPE
+ * | 2 bits, 00 = no children : FLAG_GROUP_ADDRESS_TYPE_NOADDRESS
+ * f | 01 = 1 byte : FLAG_GROUP_ADDRESS_TYPE_ONEBYTE
+ * l | 10 = 2 bytes : FLAG_GROUP_ADDRESS_TYPE_TWOBYTES
+ * a | 11 = 3 bytes : FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
+ * g | ELSE
+ * s | is moved ? 2 bits, 11 = no
+ * | 01 = yes
+ * | the new address is stored in the same place as the parent address
+ * | has several chars ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_MULTIPLE_CHARS
+ * | has a terminal ? 1 bit, 1 = yes, 0 = no : FLAG_IS_TERMINAL
* | has shortcut targets ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_SHORTCUT_TARGETS
* | has bigrams ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_BIGRAMS
* | is not a word ? 1 bit, 1 = yes, 0 = no : FLAG_IS_NOT_A_WORD
@@ -178,6 +183,7 @@ public final class FormatSpec {
static final int FLAG_HAS_BIGRAMS = 0x04;
static final int FLAG_IS_NOT_A_WORD = 0x02;
static final int FLAG_IS_BLACKLISTED = 0x01;
+ static final int FLAG_IS_MOVED = 0x40;
static final int FLAG_ATTRIBUTE_HAS_NEXT = 0x80;
static final int FLAG_ATTRIBUTE_OFFSET_NEGATIVE = 0x40;
--
cgit v1.2.3-83-g751a
From 2aea34fb31f1a8a5fe24cccd1b9aab4908f2f8e2 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Wed, 26 Sep 2012 13:21:29 +0900
Subject: Add updateParentAddress.
bug: 6669677
Change-Id: I353f8ae53720cdf7a809271a28cb703709609f53
---
.../latin/makedict/BinaryDictIOUtils.java | 30 ++++++++++++++++++++++
1 file changed, 30 insertions(+)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index e2c1254ce..b97be0543 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -246,4 +246,34 @@ public class BinaryDictIOUtils {
buffer.position(wordPosition);
buffer.put((byte)newFlags);
}
+
+ private static void putSInt24(final FusionDictionaryBufferInterface buffer,
+ final int value) {
+ final int absValue = Math.abs(value);
+ buffer.put((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
+ buffer.put((byte)((absValue >> 8) & 0xFF));
+ buffer.put((byte)(absValue & 0xFF));
+ }
+
+ /**
+ * Update a parent address in a CharGroup that is addressed by groupOriginAddress.
+ *
+ * @param buffer the buffer to write.
+ * @param groupOriginAddress the address of the group.
+ * @param newParentAddress the absolute address of the parent.
+ * @param formatOptions file format options.
+ */
+ public static void updateParentAddress(final FusionDictionaryBufferInterface buffer,
+ final int groupOriginAddress, final int newParentAddress,
+ final FormatOptions formatOptions) {
+ final int originalPosition = buffer.position();
+ buffer.position(groupOriginAddress);
+ if (!formatOptions.mSupportsDynamicUpdate) {
+ throw new RuntimeException("this file format does not support parent addresses");
+ }
+ final int flags = buffer.readUnsignedByte();
+ final int parentOffset = newParentAddress - groupOriginAddress;
+ putSInt24(buffer, parentOffset);
+ buffer.position(originalPosition);
+ }
}
--
cgit v1.2.3-83-g751a
From 84d858ed5e187eb9d4b56b593e1d9287f762bbca Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Mon, 20 Aug 2012 19:29:20 +0900
Subject: Use BinaryDictInputOutput to save UserHistoryDictionary.
bug: 6669677
Change-Id: I08193c26f76dbd48168f8ac02c1b737525bfc7b2
---
.../inputmethod/latin/UserHistoryDictIOUtils.java | 28 +-
.../inputmethod/latin/UserHistoryDictionary.java | 482 ++++++---------------
.../latin/makedict/BinaryDictIOUtils.java | 5 +-
.../latin/UserHistoryDictionaryTests.java | 109 +++++
4 files changed, 270 insertions(+), 354 deletions(-)
create mode 100644 tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
index 05255a6b3..519165dd0 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
@@ -115,11 +115,10 @@ public class UserHistoryDictIOUtils {
public static void writeDictionaryBinary(final OutputStream destination,
final BigramDictionaryInterface dict, final UserHistoryDictionaryBigramList bigrams,
final FormatOptions formatOptions) {
-
final FusionDictionary fusionDict = constructFusionDictionary(dict, bigrams);
-
try {
BinaryDictInputOutput.writeDictionaryBinary(destination, fusionDict, formatOptions);
+ Log.d(TAG, "end writing");
} catch (IOException e) {
Log.e(TAG, "IO exception while writing file: " + e);
} catch (UnsupportedFormatException e) {
@@ -132,16 +131,18 @@ public class UserHistoryDictIOUtils {
*/
/* packages for test */ static FusionDictionary constructFusionDictionary(
final BigramDictionaryInterface dict, final UserHistoryDictionaryBigramList bigrams) {
-
final FusionDictionary fusionDict = new FusionDictionary(new Node(),
- new FusionDictionary.DictionaryOptions(
- new HashMap(), false, false));
-
+ new FusionDictionary.DictionaryOptions(new HashMap(), false,
+ false));
+ int profTotal = 0;
for (final String word1 : bigrams.keySet()) {
final HashMap word1Bigrams = bigrams.getBigrams(word1);
for (final String word2 : word1Bigrams.keySet()) {
final int freq = dict.getFrequency(word1, word2);
-
+ if (freq == -1) {
+ // don't add this bigram.
+ continue;
+ }
if (DEBUG) {
if (word1 == null) {
Log.d(TAG, "add unigram: " + word2 + "," + Integer.toString(freq));
@@ -149,17 +150,22 @@ public class UserHistoryDictIOUtils {
Log.d(TAG, "add bigram: " + word1
+ "," + word2 + "," + Integer.toString(freq));
}
+ profTotal++;
}
-
if (word1 == null) { // unigram
fusionDict.add(word2, freq, null, false /* isNotAWord */);
} else { // bigram
+ if (FusionDictionary.findWordInTree(fusionDict.mRoot, word1) == null) {
+ fusionDict.add(word1, 2, null, false /* isNotAWord */);
+ }
fusionDict.setBigram(word1, word2, freq);
}
bigrams.updateBigram(word1, word2, (byte)freq);
}
}
-
+ if (DEBUG) {
+ Log.d(TAG, "add " + profTotal + "words");
+ }
return fusionDict;
}
@@ -171,7 +177,6 @@ public class UserHistoryDictIOUtils {
final Map unigrams = CollectionUtils.newTreeMap();
final Map frequencies = CollectionUtils.newTreeMap();
final Map> bigrams = CollectionUtils.newTreeMap();
-
try {
BinaryDictIOUtils.readUnigramsAndBigramsBinary(buffer, unigrams, frequencies,
bigrams);
@@ -189,14 +194,11 @@ public class UserHistoryDictIOUtils {
/* package for test */ static void addWordsFromWordMap(final Map unigrams,
final Map frequencies,
final Map> bigrams, final OnAddWordListener to) {
-
for (Map.Entry entry : unigrams.entrySet()) {
final String word1 = entry.getValue();
final int unigramFrequency = frequencies.get(entry.getKey());
to.setUnigram(word1, null, unigramFrequency);
-
final ArrayList attrList = bigrams.get(entry.getKey());
-
if (attrList != null) {
for (final PendingAttribute attr : attrList) {
to.setBigram(word1, unigrams.get(attr.mAddress),
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
index e03af649c..202aa642f 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
@@ -16,24 +16,25 @@
package com.android.inputmethod.latin;
-import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
import android.os.AsyncTask;
-import android.provider.BaseColumns;
import android.util.Log;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.UserHistoryDictIOUtils.BigramDictionaryInterface;
+import com.android.inputmethod.latin.UserHistoryDictIOUtils.OnAddWordListener;
import com.android.inputmethod.latin.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
@@ -43,45 +44,27 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class UserHistoryDictionary extends ExpandableDictionary {
private static final String TAG = UserHistoryDictionary.class.getSimpleName();
+ private static final String NAME = UserHistoryDictionary.class.getSimpleName();
public static final boolean DBG_SAVE_RESTORE = false;
public static final boolean DBG_STRESS_TEST = false;
public static final boolean DBG_ALWAYS_WRITE = false;
public static final boolean PROFILE_SAVE_RESTORE = LatinImeLogger.sDBG;
+ private static final FormatOptions VERSION3 = new FormatOptions(3,
+ true /* supportsDynamicUpdate */);
+
/** Any pair being typed or picked */
private static final int FREQUENCY_FOR_TYPED = 2;
/** Maximum number of pairs. Pruning will start when databases goes above this number. */
- public static final int sMaxHistoryBigrams = 10000;
+ public static final int MAX_HISTORY_BIGRAMS = 10000;
/**
* When it hits maximum bigram pair, it will delete until you are left with
* only (sMaxHistoryBigrams - sDeleteHistoryBigrams) pairs.
* Do not keep this number small to avoid deleting too often.
*/
- public static final int sDeleteHistoryBigrams = 1000;
-
- /**
- * Database version should increase if the database structure changes
- */
- private static final int DATABASE_VERSION = 1;
-
- private static final String DATABASE_NAME = "userbigram_dict.db";
-
- /** Name of the words table in the database */
- private static final String MAIN_TABLE_NAME = "main";
- // TODO: Consume less space by using a unique id for locale instead of the whole
- // 2-5 character string.
- private static final String MAIN_COLUMN_ID = BaseColumns._ID;
- private static final String MAIN_COLUMN_WORD1 = "word1";
- private static final String MAIN_COLUMN_WORD2 = "word2";
- private static final String MAIN_COLUMN_LOCALE = "locale";
-
- /** Name of the frequency table in the database */
- private static final String FREQ_TABLE_NAME = "frequency";
- private static final String FREQ_COLUMN_ID = BaseColumns._ID;
- private static final String FREQ_COLUMN_PAIR_ID = "pair_id";
- private static final String COLUMN_FORGETTING_CURVE_VALUE = "freq";
+ public static final int DELETE_HISTORY_BIGRAMS = 1000;
/** Locale for which this user history dictionary is storing words */
private final String mLocale;
@@ -91,29 +74,13 @@ public class UserHistoryDictionary extends ExpandableDictionary {
private final ReentrantLock mBigramListLock = new ReentrantLock();
private final SharedPreferences mPrefs;
- private final static HashMap sDictProjectionMap;
- private final static ConcurrentHashMap>
- sLangDictCache = CollectionUtils.newConcurrentHashMap();
-
- static {
- sDictProjectionMap = CollectionUtils.newHashMap();
- sDictProjectionMap.put(MAIN_COLUMN_ID, MAIN_COLUMN_ID);
- sDictProjectionMap.put(MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD1);
- sDictProjectionMap.put(MAIN_COLUMN_WORD2, MAIN_COLUMN_WORD2);
- sDictProjectionMap.put(MAIN_COLUMN_LOCALE, MAIN_COLUMN_LOCALE);
-
- sDictProjectionMap.put(FREQ_COLUMN_ID, FREQ_COLUMN_ID);
- sDictProjectionMap.put(FREQ_COLUMN_PAIR_ID, FREQ_COLUMN_PAIR_ID);
- sDictProjectionMap.put(COLUMN_FORGETTING_CURVE_VALUE, COLUMN_FORGETTING_CURVE_VALUE);
- }
-
- private static DatabaseHelper sOpenHelper = null;
+ // Should always be false except when we use this class for test
+ /* package for test */ boolean isTest = false;
- public String getLocale() {
- return mLocale;
- }
+ private static final ConcurrentHashMap>
+ sLangDictCache = CollectionUtils.newConcurrentHashMap();
- public synchronized static UserHistoryDictionary getInstance(
+ public static synchronized UserHistoryDictionary getInstance(
final Context context, final String locale, final SharedPreferences sp) {
if (sLangDictCache.containsKey(locale)) {
final SoftReference ref = sLangDictCache.get(locale);
@@ -136,9 +103,6 @@ public class UserHistoryDictionary extends ExpandableDictionary {
super(context, Dictionary.TYPE_USER_HISTORY);
mLocale = locale;
mPrefs = sp;
- if (sOpenHelper == null) {
- sOpenHelper = new DatabaseHelper(getContext());
- }
if (mLocale != null && mLocale.length() > 1) {
loadDictionary();
}
@@ -190,6 +154,7 @@ public class UserHistoryDictionary extends ExpandableDictionary {
try {
super.addWord(
word2, null /* the "shortcut" parameter is null */, FREQUENCY_FOR_TYPED);
+ mBigramList.addBigram(null, word2, (byte)FREQUENCY_FOR_TYPED);
// Do not insert a word as a bigram of itself
if (word2.equals(word1)) {
return 0;
@@ -227,11 +192,8 @@ public class UserHistoryDictionary extends ExpandableDictionary {
* Schedules a background thread to write any pending words to the database.
*/
private void flushPendingWrites() {
- if (mBigramListLock.isLocked()) {
- return;
- }
// Create a background thread to write the pending entries
- new UpdateDbTask(sOpenHelper, mBigramList, mLocale, this, mPrefs).execute();
+ new UpdateBinaryTask(mBigramList, mLocale, this, mPrefs, getContext()).execute();
}
@Override
@@ -245,6 +207,8 @@ public class UserHistoryDictionary extends ExpandableDictionary {
}
}
+ private int profTotal;
+
private void loadDictionaryAsyncLocked() {
if (DBG_STRESS_TEST) {
try {
@@ -257,343 +221,181 @@ public class UserHistoryDictionary extends ExpandableDictionary {
final long last = SettingsValues.getLastUserHistoryWriteTime(mPrefs, mLocale);
final boolean initializing = last == 0;
final long now = System.currentTimeMillis();
- // Load the words that correspond to the current input locale
- final Cursor cursor = query(MAIN_COLUMN_LOCALE + "=?", new String[] { mLocale });
- if (null == cursor) return;
- try {
- // TODO: Call SQLiteDataBase.beginTransaction / SQLiteDataBase.endTransaction
- if (cursor.moveToFirst()) {
- final int word1Index = cursor.getColumnIndex(MAIN_COLUMN_WORD1);
- final int word2Index = cursor.getColumnIndex(MAIN_COLUMN_WORD2);
- final int fcIndex = cursor.getColumnIndex(COLUMN_FORGETTING_CURVE_VALUE);
- while (!cursor.isAfterLast()) {
- final String word1 = cursor.getString(word1Index);
- final String word2 = cursor.getString(word2Index);
- final int fc = cursor.getInt(fcIndex);
+ profTotal = 0;
+ final String fileName = NAME + "." + mLocale + ".dict";
+ final ExpandableDictionary dictionary = this;
+ final OnAddWordListener listener = new OnAddWordListener() {
+ @Override
+ public void setUnigram(String word, String shortcutTarget, int frequency) {
+ profTotal++;
+ if (DBG_SAVE_RESTORE) {
+ Log.d(TAG, "load unigram: " + word + "," + frequency);
+ }
+ dictionary.addWord(word, shortcutTarget, frequency);
+ mBigramList.addBigram(null, word, (byte)frequency);
+ }
+
+ @Override
+ public void setBigram(String word1, String word2, int frequency) {
+ if (word1.length() < BinaryDictionary.MAX_WORD_LENGTH
+ && word2.length() < BinaryDictionary.MAX_WORD_LENGTH) {
+ profTotal++;
if (DBG_SAVE_RESTORE) {
- Log.d(TAG, "--- Load user history: " + word1 + ", " + word2 + ","
- + mLocale + "," + this);
- }
- // Safeguard against adding really long words. Stack may overflow due
- // to recursive lookup
- if (null == word1) {
- super.addWord(word2, null /* shortcut */, fc);
- } else if (word1.length() < BinaryDictionary.MAX_WORD_LENGTH
- && word2.length() < BinaryDictionary.MAX_WORD_LENGTH) {
- super.setBigramAndGetFrequency(
- word1, word2, initializing ? new ForgettingCurveParams(true)
- : new ForgettingCurveParams(fc, now, last));
+ Log.d(TAG, "load bigram: " + word1 + "," + word2 + "," + frequency);
}
- mBigramList.addBigram(word1, word2, (byte)fc);
- cursor.moveToNext();
+ dictionary.setBigramAndGetFrequency(
+ word1, word2, initializing ? new ForgettingCurveParams(true)
+ : new ForgettingCurveParams(frequency, now, last));
}
+ mBigramList.addBigram(word1, word2, (byte)frequency);
}
+ };
+
+ // Load the dictionary from binary file
+ FileInputStream inStream = null;
+ try {
+ final File file = new File(getContext().getFilesDir(), fileName);
+ final byte[] buffer = new byte[(int)file.length()];
+ inStream = new FileInputStream(file);
+ inStream.read(buffer);
+ UserHistoryDictIOUtils.readDictionaryBinary(
+ new UserHistoryDictIOUtils.ByteArrayWrapper(buffer), listener);
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "when loading: file not found" + e);
+ } catch (IOException e) {
+ Log.e(TAG, "IOException when open bytebuffer: " + e);
} finally {
- cursor.close();
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
if (PROFILE_SAVE_RESTORE) {
final long diff = System.currentTimeMillis() - now;
- Log.w(TAG, "PROF: Load User HistoryDictionary: "
- + mLocale + ", " + diff + "ms.");
+ Log.d(TAG, "PROF: Load UserHistoryDictionary: "
+ + mLocale + ", " + diff + "ms. load " + profTotal + "entries.");
}
}
}
/**
- * Query the database
+ * Async task to write pending words to the binarydicts.
*/
- private static Cursor query(String selection, String[] selectionArgs) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
- // main INNER JOIN frequency ON (main._id=freq.pair_id)
- qb.setTables(MAIN_TABLE_NAME + " INNER JOIN " + FREQ_TABLE_NAME + " ON ("
- + MAIN_TABLE_NAME + "." + MAIN_COLUMN_ID + "=" + FREQ_TABLE_NAME + "."
- + FREQ_COLUMN_PAIR_ID +")");
-
- qb.setProjectionMap(sDictProjectionMap);
-
- // Get the database and run the query
- try {
- SQLiteDatabase db = sOpenHelper.getReadableDatabase();
- Cursor c = qb.query(db,
- new String[] {
- MAIN_COLUMN_WORD1, MAIN_COLUMN_WORD2, COLUMN_FORGETTING_CURVE_VALUE },
- selection, selectionArgs, null, null, null);
- return c;
- } catch (android.database.sqlite.SQLiteCantOpenDatabaseException e) {
- // Can't open the database : presumably we can't access storage. That may happen
- // when the device is wedged; do a best effort to still start the keyboard.
- return null;
- }
- }
-
- /**
- * This class helps open, create, and upgrade the database file.
- */
- private static class DatabaseHelper extends SQLiteOpenHelper {
-
- DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("PRAGMA foreign_keys = ON;");
- db.execSQL("CREATE TABLE " + MAIN_TABLE_NAME + " ("
- + MAIN_COLUMN_ID + " INTEGER PRIMARY KEY,"
- + MAIN_COLUMN_WORD1 + " TEXT,"
- + MAIN_COLUMN_WORD2 + " TEXT,"
- + MAIN_COLUMN_LOCALE + " TEXT"
- + ");");
- db.execSQL("CREATE TABLE " + FREQ_TABLE_NAME + " ("
- + FREQ_COLUMN_ID + " INTEGER PRIMARY KEY,"
- + FREQ_COLUMN_PAIR_ID + " INTEGER,"
- + COLUMN_FORGETTING_CURVE_VALUE + " INTEGER,"
- + "FOREIGN KEY(" + FREQ_COLUMN_PAIR_ID + ") REFERENCES " + MAIN_TABLE_NAME
- + "(" + MAIN_COLUMN_ID + ")" + " ON DELETE CASCADE"
- + ");");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will destroy all old data");
- db.execSQL("DROP TABLE IF EXISTS " + MAIN_TABLE_NAME);
- db.execSQL("DROP TABLE IF EXISTS " + FREQ_TABLE_NAME);
- onCreate(db);
- }
- }
-
- /**
- * Async task to write pending words to the database so that it stays in sync with
- * the in-memory trie.
- */
- private static class UpdateDbTask extends AsyncTask {
+ private static class UpdateBinaryTask extends AsyncTask
+ implements BigramDictionaryInterface {
private final UserHistoryDictionaryBigramList mBigramList;
- private final DatabaseHelper mDbHelper;
+ private final boolean mAddLevel0Bigrams;
private final String mLocale;
private final UserHistoryDictionary mUserHistoryDictionary;
private final SharedPreferences mPrefs;
+ private final Context mContext;
- public UpdateDbTask(
- DatabaseHelper openHelper, UserHistoryDictionaryBigramList pendingWrites,
- String locale, UserHistoryDictionary dict, SharedPreferences prefs) {
+ public UpdateBinaryTask(UserHistoryDictionaryBigramList pendingWrites, String locale,
+ UserHistoryDictionary dict, SharedPreferences prefs, Context context) {
mBigramList = pendingWrites;
mLocale = locale;
- mDbHelper = openHelper;
mUserHistoryDictionary = dict;
mPrefs = prefs;
- }
-
- /** Prune any old data if the database is getting too big. */
- private static void checkPruneData(SQLiteDatabase db) {
- db.execSQL("PRAGMA foreign_keys = ON;");
- Cursor c = db.query(FREQ_TABLE_NAME, new String[] { FREQ_COLUMN_PAIR_ID },
- null, null, null, null, null);
- try {
- int totalRowCount = c.getCount();
- // prune out old data if we have too much data
- if (totalRowCount > sMaxHistoryBigrams) {
- int numDeleteRows = (totalRowCount - sMaxHistoryBigrams)
- + sDeleteHistoryBigrams;
- int pairIdColumnId = c.getColumnIndex(FREQ_COLUMN_PAIR_ID);
- c.moveToFirst();
- int count = 0;
- while (count < numDeleteRows && !c.isAfterLast()) {
- String pairId = c.getString(pairIdColumnId);
- // Deleting from MAIN table will delete the frequencies
- // due to FOREIGN KEY .. ON DELETE CASCADE
- db.delete(MAIN_TABLE_NAME, MAIN_COLUMN_ID + "=?",
- new String[] { pairId });
- c.moveToNext();
- count++;
- }
- }
- } finally {
- c.close();
- }
+ mContext = context;
+ mAddLevel0Bigrams = mBigramList.size() <= MAX_HISTORY_BIGRAMS;
}
@Override
protected Void doInBackground(Void... v) {
- SQLiteDatabase db = null;
- if (mUserHistoryDictionary.mBigramListLock.tryLock()) {
+ if (mUserHistoryDictionary.isTest) {
+ // If isTest == true, wait until the lock is released.
+ mUserHistoryDictionary.mBigramListLock.lock();
try {
- try {
- db = mDbHelper.getWritableDatabase();
- } catch (android.database.sqlite.SQLiteCantOpenDatabaseException e) {
- // If we can't open the db, don't do anything. Exit through the next test
- // for non-nullity of the db variable.
- }
- if (null == db) {
- // Not much we can do. Just exit.
- return null;
- }
- db.beginTransaction();
- return doLoadTaskLocked(db);
+ doWriteTaskLocked();
} finally {
- if (db != null) {
- db.endTransaction();
- }
mUserHistoryDictionary.mBigramListLock.unlock();
}
+ } else if (mUserHistoryDictionary.mBigramListLock.tryLock()) {
+ doWriteTaskLocked();
}
return null;
}
- private Void doLoadTaskLocked(SQLiteDatabase db) {
+ private void doWriteTaskLocked() {
if (DBG_STRESS_TEST) {
try {
Log.w(TAG, "Start stress in closing: " + mLocale);
Thread.sleep(15000);
Log.w(TAG, "End stress in closing");
} catch (InterruptedException e) {
+ Log.e(TAG, "In stress test: " + e);
}
}
+
final long now = PROFILE_SAVE_RESTORE ? System.currentTimeMillis() : 0;
- int profTotal = 0;
- int profInsert = 0;
- int profDelete = 0;
- db.execSQL("PRAGMA foreign_keys = ON;");
- final boolean addLevel0Bigram = mBigramList.size() <= sMaxHistoryBigrams;
-
- // Write all the entries to the db
- for (String word1 : mBigramList.keySet()) {
- final HashMap word1Bigrams = mBigramList.getBigrams(word1);
- for (String word2 : word1Bigrams.keySet()) {
- if (PROFILE_SAVE_RESTORE) {
- ++profTotal;
- }
- // Get new frequency. Do not insert unigrams/bigrams which freq is "-1".
- final int freq; // -1, or 0~255
- if (word1 == null) { // unigram
- freq = FREQUENCY_FOR_TYPED;
- final byte prevFc = word1Bigrams.get(word2);
- if (prevFc == FREQUENCY_FOR_TYPED) {
- // No need to update since we found no changes for this entry.
- // Just skip to the next entry.
- if (DBG_SAVE_RESTORE) {
- Log.d(TAG, "Skip update user history: " + word1 + "," + word2
- + "," + prevFc);
- }
- if (!DBG_ALWAYS_WRITE) {
- continue;
- }
- }
- } else { // bigram
- final NextWord nw = mUserHistoryDictionary.getBigramWord(word1, word2);
- if (nw != null) {
- final ForgettingCurveParams fcp = nw.getFcParams();
- final byte prevFc = word1Bigrams.get(word2);
- final byte fc = (byte)fcp.getFc();
- final boolean isValid = fcp.isValid();
- if (prevFc > 0 && prevFc == fc) {
- // No need to update since we found no changes for this entry.
- // Just skip to the next entry.
- if (DBG_SAVE_RESTORE) {
- Log.d(TAG, "Skip update user history: " + word1 + ","
- + word2 + "," + prevFc);
- }
- if (!DBG_ALWAYS_WRITE) {
- continue;
- } else {
- freq = fc;
- }
- } else if (UserHistoryForgettingCurveUtils.
- needsToSave(fc, isValid, addLevel0Bigram)) {
- freq = fc;
- } else {
- // Delete this entry
- freq = -1;
- }
- } else {
- // Delete this entry
- freq = -1;
- }
- }
- // TODO: this process of making a text search for each pair each time
- // is terribly inefficient. Optimize this.
- // Find pair id
- Cursor c = null;
+ final String fileName = NAME + "." + mLocale + ".dict";
+ final File file = new File(mContext.getFilesDir(), fileName);
+ FileOutputStream out = null;
+
+ try {
+ out = new FileOutputStream(file);
+ UserHistoryDictIOUtils.writeDictionaryBinary(out, this, mBigramList, VERSION3);
+ out.flush();
+ out.close();
+ } catch (IOException e) {
+ Log.e(TAG, "IO Exception while writing file: " + e);
+ } finally {
+ if (out != null) {
try {
- if (null != word1) {
- c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID },
- MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND "
- + MAIN_COLUMN_LOCALE + "=?",
- new String[] { word1, word2, mLocale }, null, null,
- null);
- } else {
- c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID },
- MAIN_COLUMN_WORD1 + " IS NULL AND " + MAIN_COLUMN_WORD2
- + "=? AND " + MAIN_COLUMN_LOCALE + "=?",
- new String[] { word2, mLocale }, null, null, null);
- }
-
- final int pairId;
- if (c.moveToFirst()) {
- if (PROFILE_SAVE_RESTORE) {
- ++profDelete;
- }
- // Delete existing pair
- pairId = c.getInt(c.getColumnIndex(MAIN_COLUMN_ID));
- db.delete(FREQ_TABLE_NAME, FREQ_COLUMN_PAIR_ID + "=?",
- new String[] { Integer.toString(pairId) });
- } else {
- // Create new pair
- Long pairIdLong = db.insert(MAIN_TABLE_NAME, null,
- getContentValues(word1, word2, mLocale));
- pairId = pairIdLong.intValue();
- }
- // Eliminate freq == 0 because that word is profanity.
- if (freq > 0) {
- if (PROFILE_SAVE_RESTORE) {
- ++profInsert;
- }
- if (DBG_SAVE_RESTORE) {
- Log.d(TAG, "--- Save user history: " + word1 + ", " + word2
- + mLocale + "," + this);
- }
- // Insert new frequency
- db.insert(FREQ_TABLE_NAME, null,
- getFrequencyContentValues(pairId, freq));
- // Update an existing bigram entry in mBigramList too in order to
- // synchronize the SQL DB and mBigramList.
- mBigramList.updateBigram(word1, word2, (byte)freq);
- }
- } finally {
- if (c != null) {
- c.close();
- }
+ out.close();
+ } catch (IOException e) {
+ // ignore
}
}
}
- checkPruneData(db);
- // Save the timestamp after we finish writing the SQL DB.
+ // Save the timestamp after we finish writing the binary dictionary.
SettingsValues.setLastUserHistoryWriteTime(mPrefs, mLocale);
if (PROFILE_SAVE_RESTORE) {
final long diff = System.currentTimeMillis() - now;
- Log.w(TAG, "PROF: Write User HistoryDictionary: " + mLocale + ", "+ diff
- + "ms. Total: " + profTotal + ". Insert: " + profInsert + ". Delete: "
- + profDelete);
+ Log.w(TAG, "PROF: Write User HistoryDictionary: " + mLocale + ", " + diff + "ms.");
}
- db.setTransactionSuccessful();
- return null;
}
- private static ContentValues getContentValues(String word1, String word2, String locale) {
- ContentValues values = new ContentValues(3);
- values.put(MAIN_COLUMN_WORD1, word1);
- values.put(MAIN_COLUMN_WORD2, word2);
- values.put(MAIN_COLUMN_LOCALE, locale);
- return values;
+ @Override
+ public int getFrequency(String word1, String word2) {
+ final int freq;
+ if (word1 == null) { // unigram
+ freq = FREQUENCY_FOR_TYPED;
+ final byte prevFc = mBigramList.getBigrams(word1).get(word2);
+ } else { // bigram
+ final NextWord nw = mUserHistoryDictionary.getBigramWord(word1, word2);
+ if (nw != null) {
+ final ForgettingCurveParams fcp = nw.getFcParams();
+ final byte prevFc = mBigramList.getBigrams(word1).get(word2);
+ final byte fc = fcp.getFc();
+ final boolean isValid = fcp.isValid();
+ if (prevFc > 0 && prevFc == fc) {
+ freq = ((int)fc) & 0xFF;
+ } else if (UserHistoryForgettingCurveUtils.
+ needsToSave(fc, isValid, mAddLevel0Bigrams)) {
+ freq = ((int)fc) & 0xFF;
+ } else {
+ // Delete this entry
+ freq = -1;
+ }
+ } else {
+ // Delete this entry
+ freq = -1;
+ }
+ }
+ return freq;
}
+ }
- private static ContentValues getFrequencyContentValues(int pairId, int frequency) {
- ContentValues values = new ContentValues(2);
- values.put(FREQ_COLUMN_PAIR_ID, pairId);
- values.put(COLUMN_FORGETTING_CURVE_VALUE, frequency);
- return values;
+ void forceAddWordForTest(final String word1, final String word2, final boolean isValid) {
+ mBigramListLock.lock();
+ try {
+ addToUserHistory(word1, word2, isValid);
+ } finally {
+ mBigramListLock.unlock();
}
}
-
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index b97be0543..a1606db60 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -77,7 +77,10 @@ public class BinaryDictIOUtils {
p.mAddress += BinaryDictInputOutput.getGroupCountSize(p.mNumOfCharGroup);
p.mPosition = 0;
}
-
+ if (p.mNumOfCharGroup == 0) {
+ stack.pop();
+ continue;
+ }
CharGroupInfo info = BinaryDictInputOutput.readCharGroup(buffer,
p.mAddress - headerSize, formatOptions);
for (int i = 0; i < info.mCharacters.length; ++i) {
diff --git a/tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java b/tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java
new file mode 100644
index 000000000..f2a17d206
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/UserHistoryDictionaryTests.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 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.latin;
+
+import com.android.inputmethod.latin.UserHistoryDictionary;
+
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+/**
+ * Unit tests for UserHistoryDictionary
+ */
+public class UserHistoryDictionaryTests extends AndroidTestCase {
+ private static final String TAG = UserHistoryDictionaryTests.class.getSimpleName();
+ private SharedPreferences mPrefs;
+
+ private static final String[] CHARACTERS = {
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
+ "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
+ };
+
+ @Override
+ public void setUp() {
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
+ }
+
+ /**
+ * Generates a random word.
+ */
+ private String generateWord(final int value) {
+ final int lengthOfChars = CHARACTERS.length;
+ StringBuilder builder = new StringBuilder();
+ long lvalue = Math.abs((long)value);
+ while (lvalue > 0) {
+ builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]);
+ lvalue /= lengthOfChars;
+ }
+ return builder.toString();
+ }
+
+ private List generateWords(final int number, final Random random) {
+ final Set wordSet = CollectionUtils.newHashSet();
+ while (wordSet.size() < number) {
+ wordSet.add(generateWord(random.nextInt()));
+ }
+ return new ArrayList(wordSet);
+ }
+
+ private void addToDict(final UserHistoryDictionary dict, final List words) {
+ String prevWord = null;
+ for (String word : words) {
+ dict.forceAddWordForTest(prevWord, word, true);
+ prevWord = word;
+ }
+ }
+
+ public void testRandomWords() {
+ Log.d(TAG, "This test can be used for profiling.");
+ Log.d(TAG, "Usage: please set UserHisotoryDictionary.PROFILE_SAVE_RESTORE to true.");
+ final int numberOfWords = 1000;
+ final Random random = new Random(123456);
+ List words = generateWords(numberOfWords, random);
+
+ final String locale = "testRandomWords";
+ final UserHistoryDictionary dict = UserHistoryDictionary.getInstance(getContext(),
+ locale, mPrefs);
+ dict.isTest = true;
+
+ addToDict(dict, words);
+
+ try {
+ Log.d(TAG, "waiting for adding the word ...");
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "InterruptedException: " + e);
+ }
+
+ // write to file
+ dict.close();
+
+ try {
+ Log.d(TAG, "waiting for writing ...");
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "InterruptedException: " + e);
+ }
+ }
+}
--
cgit v1.2.3-83-g751a
From a28a05e971cc242b338331a3b78276fa95188d19 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Thu, 27 Sep 2012 18:16:16 +0900
Subject: Cleanup: Make some classes as final
Change-Id: I6009b3c1950ba32b7f1e205a3db2307fe0cd688e
---
.../accessibility/AccessibilityEntityProvider.java | 2 +-
.../accessibility/AccessibleKeyboardViewProxy.java | 2 +-
.../accessibility/KeyCodeDescriptionMapper.java | 2 +-
.../inputmethod/compat/AudioManagerCompatWrapper.java | 2 +-
.../compat/InputMethodManagerCompatWrapper.java | 2 +-
java/src/com/android/inputmethod/keyboard/Key.java | 2 +-
.../com/android/inputmethod/keyboard/KeyboardId.java | 2 +-
.../inputmethod/keyboard/KeyboardLayoutSet.java | 10 +++++-----
.../android/inputmethod/keyboard/KeyboardSwitcher.java | 4 ++--
.../android/inputmethod/keyboard/MainKeyboardView.java | 4 ++--
.../android/inputmethod/keyboard/MoreKeysDetector.java | 2 +-
.../android/inputmethod/keyboard/MoreKeysKeyboard.java | 2 +-
.../inputmethod/keyboard/MoreKeysKeyboardView.java | 2 +-
.../android/inputmethod/keyboard/PointerTracker.java | 4 ++--
.../keyboard/internal/AlphabetShiftState.java | 2 +-
.../internal/GestureStrokeWithPreviewPoints.java | 2 +-
.../inputmethod/keyboard/internal/KeySpecParser.java | 4 ++--
.../inputmethod/keyboard/internal/KeyStylesSet.java | 6 +++---
.../keyboard/internal/KeyVisualAttributes.java | 2 +-
.../keyboard/internal/KeyboardCodesSet.java | 2 +-
.../keyboard/internal/KeyboardIconsSet.java | 2 +-
.../inputmethod/keyboard/internal/KeyboardRow.java | 2 +-
.../inputmethod/keyboard/internal/KeyboardState.java | 4 ++--
.../inputmethod/keyboard/internal/KeysCache.java | 2 +-
.../keyboard/internal/PointerTrackerQueue.java | 2 +-
.../keyboard/internal/PreviewPlacerView.java | 4 ++--
.../inputmethod/keyboard/internal/ShiftKeyState.java | 2 +-
.../internal/SuddenJumpingTouchEventHandler.java | 2 +-
.../inputmethod/latin/AdditionalSubtypeSettings.java | 2 +-
.../android/inputmethod/latin/AssetFileAddress.java | 2 +-
.../latin/AudioAndHapticFeedbackManager.java | 2 +-
.../com/android/inputmethod/latin/AutoCorrection.java | 2 +-
.../src/com/android/inputmethod/latin/BackupAgent.java | 2 +-
.../android/inputmethod/latin/BinaryDictionary.java | 2 +-
.../inputmethod/latin/BinaryDictionaryFileDumper.java | 3 +--
.../inputmethod/latin/BinaryDictionaryGetter.java | 6 +++---
.../com/android/inputmethod/latin/BoundedTreeSet.java | 2 +-
.../com/android/inputmethod/latin/DebugSettings.java | 2 +-
.../inputmethod/latin/DebugSettingsActivity.java | 2 +-
.../android/inputmethod/latin/DicTraverseSession.java | 2 +-
.../inputmethod/latin/DictionaryCollection.java | 2 +-
.../android/inputmethod/latin/DictionaryFactory.java | 2 +-
.../latin/DictionaryPackInstallBroadcastReceiver.java | 2 +-
.../inputmethod/latin/ExpandableDictionary.java | 10 +++++-----
.../com/android/inputmethod/latin/FileTransforms.java | 2 +-
.../com/android/inputmethod/latin/InputAttributes.java | 2 +-
.../com/android/inputmethod/latin/InputPointers.java | 2 +-
java/src/com/android/inputmethod/latin/InputView.java | 2 +-
.../android/inputmethod/latin/LastComposedWord.java | 2 +-
java/src/com/android/inputmethod/latin/LatinIME.java | 4 ++--
.../com/android/inputmethod/latin/LatinImeLogger.java | 2 +-
.../android/inputmethod/latin/ResizableIntArray.java | 2 +-
.../android/inputmethod/latin/RichInputConnection.java | 4 ++--
.../android/inputmethod/latin/SettingsActivity.java | 2 +-
.../com/android/inputmethod/latin/SubtypeLocale.java | 2 +-
.../com/android/inputmethod/latin/SubtypeSwitcher.java | 4 ++--
java/src/com/android/inputmethod/latin/Suggest.java | 5 +++--
.../com/android/inputmethod/latin/SuggestedWords.java | 4 ++--
.../SuggestionSpanPickedNotificationReceiver.java | 2 +-
.../SynchronouslyLoadedContactsBinaryDictionary.java | 2 +-
.../latin/SynchronouslyLoadedUserBinaryDictionary.java | 2 +-
.../inputmethod/latin/TargetApplicationGetter.java | 4 ++--
.../inputmethod/latin/UserHistoryDictIOUtils.java | 2 +-
.../inputmethod/latin/UserHistoryDictionary.java | 4 ++--
.../latin/UserHistoryDictionaryBigramList.java | 2 +-
.../latin/UserHistoryForgettingCurveUtils.java | 4 ++--
.../com/android/inputmethod/latin/WordComposer.java | 2 +-
.../com/android/inputmethod/latin/WordListInfo.java | 2 +-
.../com/android/inputmethod/latin/XmlParseUtils.java | 8 ++++----
.../inputmethod/latin/makedict/BinaryDictIOUtils.java | 4 ++--
.../latin/makedict/BinaryDictInputOutput.java | 4 ++--
.../inputmethod/latin/makedict/CharGroupInfo.java | 2 +-
.../android/inputmethod/latin/makedict/FormatSpec.java | 2 +-
.../inputmethod/latin/makedict/FusionDictionary.java | 18 ++++++++----------
.../inputmethod/latin/makedict/MakedictLog.java | 2 +-
.../inputmethod/latin/makedict/PendingAttribute.java | 2 +-
.../latin/makedict/UnsupportedFormatException.java | 2 +-
.../com/android/inputmethod/latin/makedict/Word.java | 2 +-
.../latin/spellcheck/AndroidSpellCheckerService.java | 6 +++---
.../latin/spellcheck/AndroidSpellCheckerSession.java | 2 +-
.../AndroidWordLevelSpellCheckerSession.java | 4 ++--
.../inputmethod/latin/spellcheck/DictAndProximity.java | 2 +-
.../inputmethod/latin/spellcheck/DictionaryPool.java | 2 +-
.../latin/spellcheck/SpellCheckerProximityInfo.java | 6 +++---
.../latin/spellcheck/SpellCheckerSettingsActivity.java | 2 +-
.../latin/spellcheck/SpellCheckerSettingsFragment.java | 2 +-
.../inputmethod/latin/suggestions/MoreSuggestions.java | 8 ++++----
.../latin/suggestions/MoreSuggestionsView.java | 2 +-
.../latin/suggestions/SuggestionStripView.java | 6 +++---
89 files changed, 138 insertions(+), 140 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
index 5af5d044f..b9b6362fc 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
@@ -47,7 +47,7 @@ import com.android.inputmethod.latin.CollectionUtils;
* virtual views, thus conveying their logical structure.
*
*/
-public class AccessibilityEntityProvider extends AccessibilityNodeProviderCompat {
+public final class AccessibilityEntityProvider extends AccessibilityNodeProviderCompat {
private static final String TAG = AccessibilityEntityProvider.class.getSimpleName();
private static final int UNDEFINED = Integer.MIN_VALUE;
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
index 01220a58a..fcfa6d4e4 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
@@ -32,7 +32,7 @@ import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.latin.R;
-public class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
+public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy();
private InputMethodService mInputMethod;
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 5c45448a5..32618ad85 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -30,7 +30,7 @@ import com.android.inputmethod.latin.R;
import java.util.HashMap;
-public class KeyCodeDescriptionMapper {
+public final class KeyCodeDescriptionMapper {
private static final String TAG = KeyCodeDescriptionMapper.class.getSimpleName();
// The resource ID of the string spoken for obscured keys
diff --git a/java/src/com/android/inputmethod/compat/AudioManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/AudioManagerCompatWrapper.java
index b6c3e2a88..40eed91f2 100644
--- a/java/src/com/android/inputmethod/compat/AudioManagerCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/AudioManagerCompatWrapper.java
@@ -20,7 +20,7 @@ import android.media.AudioManager;
import java.lang.reflect.Method;
-public class AudioManagerCompatWrapper {
+public final class AudioManagerCompatWrapper {
private static final Method METHOD_isWiredHeadsetOn = CompatUtils.getMethod(
AudioManager.class, "isWiredHeadsetOn");
private static final Method METHOD_isBluetoothA2dpOn = CompatUtils.getMethod(
diff --git a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
index cc10a4ed2..a01c301ee 100644
--- a/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
+++ b/java/src/com/android/inputmethod/compat/InputMethodManagerCompatWrapper.java
@@ -27,7 +27,7 @@ import java.lang.reflect.Method;
// TODO: Override this class with the concrete implementation if we need to take care of the
// performance.
-public class InputMethodManagerCompatWrapper {
+public final class InputMethodManagerCompatWrapper {
private static final String TAG = InputMethodManagerCompatWrapper.class.getSimpleName();
private static final Method METHOD_switchToNextInputMethod = CompatUtils.getMethod(
InputMethodManager.class, "switchToNextInputMethod", IBinder.class, Boolean.TYPE);
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index cb120a33e..30812e8c3 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -138,7 +138,7 @@ public class Key implements Comparable {
private final OptionalAttributes mOptionalAttributes;
- private static class OptionalAttributes {
+ private static final class OptionalAttributes {
/** Text to output when pressed. This can be multiple characters, like ".com" */
public final String mOutputText;
public final int mAltCode;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 1e5277345..5e8a8f6bb 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -33,7 +33,7 @@ import java.util.Locale;
/**
* Unique identifier for each keyboard type.
*/
-public class KeyboardId {
+public final class KeyboardId {
public static final int MODE_TEXT = 0;
public static final int MODE_URL = 1;
public static final int MODE_EMAIL = 2;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index d97df7491..c7813ab02 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -61,7 +61,7 @@ import java.util.HashMap;
* A {@link KeyboardLayoutSet} needs to be created for each
* {@link android.view.inputmethod.EditorInfo}.
*/
-public class KeyboardLayoutSet {
+public final class KeyboardLayoutSet {
private static final String TAG = KeyboardLayoutSet.class.getSimpleName();
private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG;
@@ -77,7 +77,7 @@ public class KeyboardLayoutSet {
CollectionUtils.newHashMap();
private static final KeysCache sKeysCache = new KeysCache();
- public static class KeyboardLayoutSetException extends RuntimeException {
+ public static final class KeyboardLayoutSetException extends RuntimeException {
public final KeyboardId mKeyboardId;
public KeyboardLayoutSetException(final Throwable cause, final KeyboardId keyboardId) {
@@ -86,13 +86,13 @@ public class KeyboardLayoutSet {
}
}
- private static class ElementParams {
+ private static final class ElementParams {
int mKeyboardXmlId;
boolean mProximityCharsCorrectionEnabled;
public ElementParams() {}
}
- private static class Params {
+ private static final class Params {
String mKeyboardLayoutSetName;
int mMode;
EditorInfo mEditorInfo;
@@ -203,7 +203,7 @@ public class KeyboardLayoutSet {
params.mLanguageSwitchKeyEnabled);
}
- public static class Builder {
+ public static final class Builder {
private final Context mContext;
private final String mPackageName;
private final Resources mResources;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index fd789f029..88d7b667f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -39,12 +39,12 @@ import com.android.inputmethod.latin.SettingsValues;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.WordComposer;
-public class KeyboardSwitcher implements KeyboardState.SwitchActions {
+public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private static final String TAG = KeyboardSwitcher.class.getSimpleName();
public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916";
- static class KeyboardTheme {
+ static final class KeyboardTheme {
public final int mThemeId;
public final int mStyleId;
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index f1fcfe785..b4c9c7d6f 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -83,7 +83,7 @@ import java.util.WeakHashMap;
* @attr ref R.styleable#MainKeyboardView_ignoreAltCodeKeyTimeout
* @attr ref R.styleable#MainKeyboardView_showMoreKeysKeyboardAtTouchPoint
*/
-public class MainKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler,
+public final class MainKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler,
SuddenJumpingTouchEventHandler.ProcessMotionEvent {
private static final String TAG = MainKeyboardView.class.getSimpleName();
@@ -136,7 +136,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
private final KeyTimerHandler mKeyTimerHandler;
- private static class KeyTimerHandler extends StaticInnerHandlerWrapper
+ private static final class KeyTimerHandler extends StaticInnerHandlerWrapper
implements TimerProxy {
private static final int MSG_TYPING_STATE_EXPIRED = 0;
private static final int MSG_REPEAT_KEY = 1;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
index cd4e3001e..a2001cb8f 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysDetector.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.keyboard;
-public class MoreKeysDetector extends KeyDetector {
+public final class MoreKeysDetector extends KeyDetector {
private final int mSlideAllowanceSquare;
private final int mSlideAllowanceSquareTop;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index c9af888f9..d7d4be40b 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -27,7 +27,7 @@ import com.android.inputmethod.keyboard.internal.MoreKeySpec;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StringUtils;
-public class MoreKeysKeyboard extends Keyboard {
+public final class MoreKeysKeyboard extends Keyboard {
private final int mDefaultKeyCoordX;
MoreKeysKeyboard(final MoreKeysKeyboardParams params) {
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index e513a1477..a50617693 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -33,7 +33,7 @@ import com.android.inputmethod.latin.R;
* A view that renders a virtual {@link MoreKeysKeyboard}. It handles rendering of keys and
* detecting key presses and touch movements.
*/
-public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel {
+public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel {
private final int[] mCoordinates = new int[2];
private final KeyDetector mKeyDetector;
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index ec8f65994..9dae40a93 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -34,7 +34,7 @@ import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayList;
-public class PointerTracker implements PointerTrackerQueue.Element {
+public final class PointerTracker implements PointerTrackerQueue.Element {
private static final String TAG = PointerTracker.class.getSimpleName();
private static final boolean DEBUG_EVENT = false;
private static final boolean DEBUG_MOVE_EVENT = false;
@@ -121,7 +121,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
}
}
- static class PointerTrackerParams {
+ static final class PointerTrackerParams {
public final boolean mSlidingKeyInputEnabled;
public final int mTouchNoiseThresholdTime;
public final float mTouchNoiseThresholdDistance;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/AlphabetShiftState.java b/java/src/com/android/inputmethod/keyboard/internal/AlphabetShiftState.java
index 5712df1fc..44aa72a0a 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/AlphabetShiftState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/AlphabetShiftState.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
-public class AlphabetShiftState {
+public final class AlphabetShiftState {
private static final String TAG = AlphabetShiftState.class.getSimpleName();
private static final boolean DEBUG = false;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
index 3487b5018..5b3f31805 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
@@ -16,7 +16,7 @@ package com.android.inputmethod.keyboard.internal;
import com.android.inputmethod.latin.ResizableIntArray;
-public class GestureStrokeWithPreviewPoints extends GestureStroke {
+public final class GestureStrokeWithPreviewPoints extends GestureStroke {
public static final int PREVIEW_CAPACITY = 256;
private final ResizableIntArray mPreviewEventTimes = new ResizableIntArray(PREVIEW_CAPACITY);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index 2a57caa5f..2caa5eb02 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -46,7 +46,7 @@ import java.util.Locale;
* Note that the '\' is also parsed by XML parser and CSV parser as well.
* See {@link KeyboardIconsSet} about icon_name.
*/
-public class KeySpecParser {
+public final class KeySpecParser {
private static final boolean DEBUG = LatinImeLogger.sDBG;
private static final int MAX_STRING_REFERENCE_INDIRECTION = 10;
@@ -318,7 +318,7 @@ public class KeySpecParser {
}
@SuppressWarnings("serial")
- public static class KeySpecParserError extends RuntimeException {
+ public static final class KeySpecParserError extends RuntimeException {
public KeySpecParserError(final String message) {
super(message);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
index 71fd30563..563d22414 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
@@ -29,7 +29,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.util.HashMap;
-public class KeyStylesSet {
+public final class KeyStylesSet {
private static final String TAG = KeyStylesSet.class.getSimpleName();
private static final boolean DEBUG = false;
@@ -45,7 +45,7 @@ public class KeyStylesSet {
mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
}
- private static class EmptyKeyStyle extends KeyStyle {
+ private static final class EmptyKeyStyle extends KeyStyle {
EmptyKeyStyle(final KeyboardTextsSet textsSet) {
super(textsSet);
}
@@ -71,7 +71,7 @@ public class KeyStylesSet {
}
}
- private static class DeclaredKeyStyle extends KeyStyle {
+ private static final class DeclaredKeyStyle extends KeyStyle {
private final HashMap mStyles;
private final String mParentStyleName;
private final SparseArray mStyleAttributes = CollectionUtils.newSparseArray();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
index 04cc152fe..6ddd2a6fb 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
@@ -23,7 +23,7 @@ import android.util.SparseIntArray;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.ResourceUtils;
-public class KeyVisualAttributes {
+public final class KeyVisualAttributes {
public final Typeface mTypeface;
public final float mLetterRatio;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
index f7923d0b9..840d7133d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
@@ -21,7 +21,7 @@ import com.android.inputmethod.latin.CollectionUtils;
import java.util.HashMap;
-public class KeyboardCodesSet {
+public final class KeyboardCodesSet {
private static final HashMap sLanguageToCodesMap = CollectionUtils.newHashMap();
private static final HashMap sNameToIdMap = CollectionUtils.newHashMap();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index 4a98a3698..7292e8e19 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -27,7 +27,7 @@ import com.android.inputmethod.latin.R;
import java.util.HashMap;
-public class KeyboardIconsSet {
+public final class KeyboardIconsSet {
private static final String TAG = KeyboardIconsSet.class.getSimpleName();
public static final int ICON_UNDEFINED = 0;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
index eb17b0ea4..b986262d7 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
@@ -32,7 +32,7 @@ import org.xmlpull.v1.XmlPullParser;
* Some of the key size defaults can be overridden per row from what the {@link Keyboard}
* defines.
*/
-public class KeyboardRow {
+public final class KeyboardRow {
// keyWidth enum constants
private static final int KEYWIDTH_NOT_ENUM = 0;
private static final int KEYWIDTH_FILL_RIGHT = -1;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 4ab6832c3..58cc8972a 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -34,7 +34,7 @@ import com.android.inputmethod.latin.Constants;
*
* The actions are {@link SwitchActions}'s methods.
*/
-public class KeyboardState {
+public final class KeyboardState {
private static final String TAG = KeyboardState.class.getSimpleName();
private static final boolean DEBUG_EVENT = false;
private static final boolean DEBUG_ACTION = false;
@@ -92,7 +92,7 @@ public class KeyboardState {
private final SavedKeyboardState mSavedKeyboardState = new SavedKeyboardState();
- static class SavedKeyboardState {
+ static final class SavedKeyboardState {
public boolean mIsValid;
public boolean mIsAlphabetMode;
public boolean mIsAlphabetShiftLocked;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
index f54617c98..d1b4c8524 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
@@ -21,7 +21,7 @@ import com.android.inputmethod.latin.CollectionUtils;
import java.util.HashMap;
-public class KeysCache {
+public final class KeysCache {
private final HashMap mMap = CollectionUtils.newHashMap();
public void clear() {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index c1a5cbead..a52f202aa 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -22,7 +22,7 @@ import com.android.inputmethod.latin.CollectionUtils;
import java.util.ArrayList;
-public class PointerTrackerQueue {
+public final class PointerTrackerQueue {
private static final String TAG = PointerTrackerQueue.class.getSimpleName();
private static final boolean DEBUG = false;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
index 72be7fc59..776ac0204 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java
@@ -39,7 +39,7 @@ import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
-public class PreviewPlacerView extends RelativeLayout {
+public final class PreviewPlacerView extends RelativeLayout {
// The height of extra area above the keyboard to draw gesture trails.
// Proportional to the keyboard height.
private static final float EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO = 0.25f;
@@ -79,7 +79,7 @@ public class PreviewPlacerView extends RelativeLayout {
private final DrawingHandler mDrawingHandler;
- private static class DrawingHandler extends StaticInnerHandlerWrapper {
+ private static final class DrawingHandler extends StaticInnerHandlerWrapper {
private static final int MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 0;
private static final int MSG_UPDATE_GESTURE_PREVIEW_TRAIL = 1;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
index edb40c8e7..90db73dee 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/ShiftKeyState.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
-/* package */ class ShiftKeyState extends ModifierKeyState {
+/* package */ final class ShiftKeyState extends ModifierKeyState {
private static final int PRESSING_ON_SHIFTED = 3; // both temporary shifted & shift locked
private static final int IGNORING = 4;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/SuddenJumpingTouchEventHandler.java b/java/src/com/android/inputmethod/keyboard/internal/SuddenJumpingTouchEventHandler.java
index a591a7ac3..c53428fe5 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/SuddenJumpingTouchEventHandler.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/SuddenJumpingTouchEventHandler.java
@@ -28,7 +28,7 @@ import com.android.inputmethod.latin.ResourceUtils;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.research.ResearchLogger;
-public class SuddenJumpingTouchEventHandler {
+public final class SuddenJumpingTouchEventHandler {
private static final String TAG = SuddenJumpingTouchEventHandler.class.getSimpleName();
private static boolean DEBUG_MODE = LatinImeLogger.sDBG;
diff --git a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
index ae51d2537..d12607721 100644
--- a/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/AdditionalSubtypeSettings.java
@@ -49,7 +49,7 @@ import com.android.inputmethod.compat.CompatUtils;
import java.util.ArrayList;
import java.util.TreeSet;
-public class AdditionalSubtypeSettings extends PreferenceFragment {
+public final class AdditionalSubtypeSettings extends PreferenceFragment {
private SharedPreferences mPrefs;
private SubtypeLocaleAdapter mSubtypeLocaleAdapter;
private KeyboardLayoutSetAdapter mKeyboardLayoutSetAdapter;
diff --git a/java/src/com/android/inputmethod/latin/AssetFileAddress.java b/java/src/com/android/inputmethod/latin/AssetFileAddress.java
index 3549a1561..29c733ba6 100644
--- a/java/src/com/android/inputmethod/latin/AssetFileAddress.java
+++ b/java/src/com/android/inputmethod/latin/AssetFileAddress.java
@@ -24,7 +24,7 @@ import java.io.File;
* the package file. Open it correctly thus requires the name of the package it is in, but
* also the offset in the file and the length of this data. This class encapsulates these three.
*/
-class AssetFileAddress {
+final class AssetFileAddress {
public final String mFilename;
public final long mOffset;
public final long mLength;
diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
index 55664d411..59ef5e09f 100644
--- a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
+++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
@@ -30,7 +30,7 @@ import com.android.inputmethod.latin.VibratorUtils;
* It offers a consistent and simple interface that allows LatinIME to forget about the
* complexity of settings and the like.
*/
-public class AudioAndHapticFeedbackManager {
+public final class AudioAndHapticFeedbackManager {
final private SettingsValues mSettingsValues;
final private AudioManager mAudioManager;
final private VibratorUtils mVibratorUtils;
diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java
index f425e360a..84fad158f 100644
--- a/java/src/com/android/inputmethod/latin/AutoCorrection.java
+++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java
@@ -23,7 +23,7 @@ import android.util.Log;
import java.util.concurrent.ConcurrentHashMap;
-public class AutoCorrection {
+public final class AutoCorrection {
private static final boolean DBG = LatinImeLogger.sDBG;
private static final String TAG = AutoCorrection.class.getSimpleName();
private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4;
diff --git a/java/src/com/android/inputmethod/latin/BackupAgent.java b/java/src/com/android/inputmethod/latin/BackupAgent.java
index ee070af75..0beb088ac 100644
--- a/java/src/com/android/inputmethod/latin/BackupAgent.java
+++ b/java/src/com/android/inputmethod/latin/BackupAgent.java
@@ -22,7 +22,7 @@ import android.app.backup.SharedPreferencesBackupHelper;
/**
* Backs up the Latin IME shared preferences.
*/
-public class BackupAgent extends BackupAgentHelper {
+public final class BackupAgent extends BackupAgentHelper {
@Override
public void onCreate() {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 9244f16b1..e084cb306 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -30,7 +30,7 @@ import java.util.Locale;
/**
* Implements a static, compacted, binary dictionary of standard words.
*/
-public class BinaryDictionary extends Dictionary {
+public final class BinaryDictionary extends Dictionary {
public static final String DICTIONARY_PACK_AUTHORITY =
"com.android.inputmethod.latin.dictionarypack";
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 799aea8ef..0b115945b 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -30,7 +30,6 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -40,7 +39,7 @@ import java.util.Locale;
* Group class for static methods to help with creation and getting of the binary dictionary
* file from the dictionary provider
*/
-public class BinaryDictionaryFileDumper {
+public final class BinaryDictionaryFileDumper {
private static final String TAG = BinaryDictionaryFileDumper.class.getSimpleName();
private static final boolean DEBUG = false;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 9764df072..fa9f79ecd 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -37,7 +37,7 @@ import java.util.Locale;
/**
* Helper class to get the address of a mmap'able dictionary file.
*/
-class BinaryDictionaryGetter {
+final class BinaryDictionaryGetter {
/**
* Used for Log actions from this class
@@ -178,7 +178,7 @@ class BinaryDictionaryGetter {
context.getApplicationInfo().sourceDir, afd.getStartOffset(), afd.getLength());
}
- static private class DictPackSettings {
+ private static final class DictPackSettings {
final SharedPreferences mDictPreferences;
public DictPackSettings(final Context context) {
Context dictPackContext = null;
@@ -237,7 +237,7 @@ class BinaryDictionaryGetter {
/**
* Utility class for the {@link #getCachedWordLists} method
*/
- private static class FileAndMatchLevel {
+ private static final class FileAndMatchLevel {
final File mFile;
final int mMatchLevel;
public FileAndMatchLevel(final File file, final int matchLevel) {
diff --git a/java/src/com/android/inputmethod/latin/BoundedTreeSet.java b/java/src/com/android/inputmethod/latin/BoundedTreeSet.java
index cf977617d..7f7ff31c8 100644
--- a/java/src/com/android/inputmethod/latin/BoundedTreeSet.java
+++ b/java/src/com/android/inputmethod/latin/BoundedTreeSet.java
@@ -25,7 +25,7 @@ import java.util.TreeSet;
/**
* A TreeSet that is bounded in size and throws everything that's smaller than its limit
*/
-public class BoundedTreeSet extends TreeSet {
+public final class BoundedTreeSet extends TreeSet {
private final int mCapacity;
public BoundedTreeSet(final Comparator comparator, final int capacity) {
super(comparator);
diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java
index 1ea14dad5..3af3cab2c 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettings.java
@@ -30,7 +30,7 @@ import android.util.Log;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.research.ResearchLogger;
-public class DebugSettings extends PreferenceFragment
+public final class DebugSettings extends PreferenceFragment
implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = DebugSettings.class.getSimpleName();
diff --git a/java/src/com/android/inputmethod/latin/DebugSettingsActivity.java b/java/src/com/android/inputmethod/latin/DebugSettingsActivity.java
index cde20606a..6ef19ee82 100644
--- a/java/src/com/android/inputmethod/latin/DebugSettingsActivity.java
+++ b/java/src/com/android/inputmethod/latin/DebugSettingsActivity.java
@@ -20,7 +20,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
-public class DebugSettingsActivity extends PreferenceActivity {
+public final class DebugSettingsActivity extends PreferenceActivity {
@Override
public Intent getIntent() {
final Intent modIntent = new Intent(super.getIntent());
diff --git a/java/src/com/android/inputmethod/latin/DicTraverseSession.java b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
index 359da72cc..ce1b64660 100644
--- a/java/src/com/android/inputmethod/latin/DicTraverseSession.java
+++ b/java/src/com/android/inputmethod/latin/DicTraverseSession.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.latin;
import java.util.Locale;
-public class DicTraverseSession {
+public final class DicTraverseSession {
static {
JniUtils.loadNativeLibrary();
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index 4acab6b05..d3b120989 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -29,7 +29,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* Class for a collection of dictionaries that behave like one dictionary.
*/
-public class DictionaryCollection extends Dictionary {
+public final class DictionaryCollection extends Dictionary {
private final String TAG = DictionaryCollection.class.getSimpleName();
protected final CopyOnWriteArrayList mDictionaries;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index cdd01d0c7..f381973ae 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -29,7 +29,7 @@ import java.util.Locale;
/**
* Factory for dictionary instances.
*/
-public class DictionaryFactory {
+public final class DictionaryFactory {
private static final String TAG = DictionaryFactory.class.getSimpleName();
// This class must be located in the same package as LatinIME.java.
private static final String RESOURCE_PACKAGE_NAME =
diff --git a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
index 9c37d7673..f2f3fbded 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryPackInstallBroadcastReceiver.java
@@ -27,7 +27,7 @@ import android.net.Uri;
/**
* Takes action to reload the necessary data when a dictionary pack was added/removed.
*/
-public class DictionaryPackInstallBroadcastReceiver extends BroadcastReceiver {
+public final class DictionaryPackInstallBroadcastReceiver extends BroadcastReceiver {
final LatinIME mService;
/**
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 8a38d1e1b..8cdc2a0af 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -48,7 +48,7 @@ public class ExpandableDictionary extends Dictionary {
// Use this lock before touching mUpdatingDictionary & mRequiresDownload
private Object mUpdatingLock = new Object();
- private static class Node {
+ private static final class Node {
Node() {}
char mCode;
int mFrequency;
@@ -60,7 +60,7 @@ public class ExpandableDictionary extends Dictionary {
LinkedList mNGrams; // Supports ngram
}
- private static class NodeArray {
+ private static final class NodeArray {
Node[] mData;
int mLength = 0;
private static final int INCREMENT = 2;
@@ -88,7 +88,7 @@ public class ExpandableDictionary extends Dictionary {
public int notifyTypedAgainAndGetFrequency();
}
- private static class NextStaticWord implements NextWord {
+ private static final class NextStaticWord implements NextWord {
public final Node mWord;
private final int mFrequency;
public NextStaticWord(Node word, int frequency) {
@@ -117,7 +117,7 @@ public class ExpandableDictionary extends Dictionary {
}
}
- private static class NextHistoryWord implements NextWord {
+ private static final class NextHistoryWord implements NextWord {
public final Node mWord;
public final ForgettingCurveParams mFcp;
@@ -703,7 +703,7 @@ public class ExpandableDictionary extends Dictionary {
mRoots = new NodeArray();
}
- private class LoadDictionaryTask extends Thread {
+ private final class LoadDictionaryTask extends Thread {
LoadDictionaryTask() {}
@Override
public void run() {
diff --git a/java/src/com/android/inputmethod/latin/FileTransforms.java b/java/src/com/android/inputmethod/latin/FileTransforms.java
index 80159521c..09cf23a9b 100644
--- a/java/src/com/android/inputmethod/latin/FileTransforms.java
+++ b/java/src/com/android/inputmethod/latin/FileTransforms.java
@@ -21,7 +21,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
-public class FileTransforms {
+public final class FileTransforms {
public static OutputStream getCryptedStream(OutputStream out) {
// Crypt the stream.
return out;
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index 7bcda9bc4..2f7608a03 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -23,7 +23,7 @@ import android.view.inputmethod.EditorInfo;
/**
* Class to hold attributes of the input field.
*/
-public class InputAttributes {
+public final class InputAttributes {
private final String TAG = InputAttributes.class.getSimpleName();
final public boolean mInputTypeNoAutoCorrect;
diff --git a/java/src/com/android/inputmethod/latin/InputPointers.java b/java/src/com/android/inputmethod/latin/InputPointers.java
index ff2feb51d..6b48aabb3 100644
--- a/java/src/com/android/inputmethod/latin/InputPointers.java
+++ b/java/src/com/android/inputmethod/latin/InputPointers.java
@@ -17,7 +17,7 @@
package com.android.inputmethod.latin;
// TODO: This class is not thread-safe.
-public class InputPointers {
+public final class InputPointers {
private final int mDefaultCapacity;
private final ResizableIntArray mXCoordinates;
private final ResizableIntArray mYCoordinates;
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index c15f45345..d7595bfbe 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -23,7 +23,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
-public class InputView extends LinearLayout {
+public final class InputView extends LinearLayout {
private View mSuggestionStripContainer;
private View mKeyboardView;
private int mKeyboardTopPadding;
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
index dd73a978c..94cdc9b85 100644
--- a/java/src/com/android/inputmethod/latin/LastComposedWord.java
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -22,7 +22,7 @@ import android.text.TextUtils;
* This class encapsulates data about a word previously composed, but that has been
* committed already. This is used for resuming suggestion, and cancel auto-correction.
*/
-public class LastComposedWord {
+public final class LastComposedWord {
// COMMIT_TYPE_USER_TYPED_WORD is used when the word committed is the exact typed word, with
// no hinting from the IME. It happens when some external event happens (rotating the device,
// for example) or when auto-correction is off by settings or editor attributes.
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b8a8f9aaf..3e893303f 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -85,7 +85,7 @@ import java.util.Locale;
/**
* Input method implementation for Qwerty'ish keyboard.
*/
-public class LatinIME extends InputMethodService implements KeyboardActionListener,
+public final class LatinIME extends InputMethodService implements KeyboardActionListener,
SuggestionStripView.Listener, TargetApplicationGetter.OnTargetApplicationKnownListener,
Suggest.SuggestInitializationListener {
private static final String TAG = LatinIME.class.getSimpleName();
@@ -183,7 +183,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public final UIHandler mHandler = new UIHandler(this);
- public static class UIHandler extends StaticInnerHandlerWrapper {
+ public static final class UIHandler extends StaticInnerHandlerWrapper {
private static final int MSG_UPDATE_SHIFT_STATE = 0;
private static final int MSG_PENDING_IMS_CALLBACK = 1;
private static final int MSG_UPDATE_SUGGESTION_STRIP = 2;
diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
index 9eab19c49..394a9c7aa 100644
--- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java
+++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
@@ -21,7 +21,7 @@ import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.keyboard.Keyboard;
-public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
+public final class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
public static boolean sDBG = false;
public static boolean sVISUALDEBUG = false;
diff --git a/java/src/com/android/inputmethod/latin/ResizableIntArray.java b/java/src/com/android/inputmethod/latin/ResizableIntArray.java
index c660f92c4..9a46f160b 100644
--- a/java/src/com/android/inputmethod/latin/ResizableIntArray.java
+++ b/java/src/com/android/inputmethod/latin/ResizableIntArray.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.latin;
import java.util.Arrays;
// TODO: This class is not thread-safe.
-public class ResizableIntArray {
+public final class ResizableIntArray {
private int[] mArray;
private int mLength;
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 28c0c0f16..1acca5860 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -41,7 +41,7 @@ import java.util.regex.Pattern;
* all the time to find out what text is in the buffer, when we need it to determine caps mode
* for example.
*/
-public class RichInputConnection {
+public final class RichInputConnection {
private static final String TAG = RichInputConnection.class.getSimpleName();
private static final boolean DBG = false;
private static final boolean DEBUG_PREVIOUS_TEXT = false;
@@ -415,7 +415,7 @@ public class RichInputConnection {
/**
* Represents a range of text, relative to the current cursor position.
*/
- public static class Range {
+ public static final class Range {
/** Characters before selection start */
public final int mCharsBefore;
diff --git a/java/src/com/android/inputmethod/latin/SettingsActivity.java b/java/src/com/android/inputmethod/latin/SettingsActivity.java
index 68f8582fc..0d3c8ebb7 100644
--- a/java/src/com/android/inputmethod/latin/SettingsActivity.java
+++ b/java/src/com/android/inputmethod/latin/SettingsActivity.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.latin;
import android.content.Intent;
import android.preference.PreferenceActivity;
-public class SettingsActivity extends PreferenceActivity {
+public final class SettingsActivity extends PreferenceActivity {
private static final String DEFAULT_FRAGMENT = Settings.class.getName();
@Override
diff --git a/java/src/com/android/inputmethod/latin/SubtypeLocale.java b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
index de5f515b0..579f96bb4 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeLocale.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeLocale.java
@@ -30,7 +30,7 @@ import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
import java.util.HashMap;
import java.util.Locale;
-public class SubtypeLocale {
+public final class SubtypeLocale {
static final String TAG = SubtypeLocale.class.getSimpleName();
// This class must be located in the same package as LatinIME.java.
private static final String RESOURCE_PACKAGE_NAME =
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index c693edcca..8e51a372b 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -38,7 +38,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
-public class SubtypeSwitcher {
+public final class SubtypeSwitcher {
private static boolean DBG = LatinImeLogger.sDBG;
private static final String TAG = SubtypeSwitcher.class.getSimpleName();
@@ -60,7 +60,7 @@ public class SubtypeSwitcher {
private boolean mIsNetworkConnected;
- static class NeedsToDisplayLanguage {
+ static final class NeedsToDisplayLanguage {
private int mEnabledSubtypeCount;
private boolean mIsSystemLanguageSameAsInputLanguage;
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 278c4b9ce..f0e3b4ebd 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -34,7 +34,7 @@ import java.util.concurrent.ConcurrentHashMap;
* This class loads a dictionary and provides a list of suggestions for a given sequence of
* characters. This includes corrections and completions.
*/
-public class Suggest {
+public final class Suggest {
public static final String TAG = Suggest.class.getSimpleName();
// Session id for
@@ -362,7 +362,8 @@ public class Suggest {
return suggestionsList;
}
- private static class SuggestedWordInfoComparator implements Comparator {
+ private static final class SuggestedWordInfoComparator
+ implements Comparator {
// This comparator ranks the word info with the higher frequency first. That's because
// that's the order we want our elements in.
@Override
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index d9f48c4a4..52e292a86 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -23,7 +23,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
-public class SuggestedWords {
+public final class SuggestedWords {
private static final ArrayList EMPTY_WORD_INFO_LIST =
CollectionUtils.newArrayList(0);
public static final SuggestedWords EMPTY = new SuggestedWords(
@@ -117,7 +117,7 @@ public class SuggestedWords {
return suggestionsList;
}
- public static class SuggestedWordInfo {
+ public static final class SuggestedWordInfo {
public static final int MAX_SCORE = Integer.MAX_VALUE;
public static final int KIND_TYPED = 0; // What user typed
public static final int KIND_CORRECTION = 1; // Simple correction/suggestion
diff --git a/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java b/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java
index 4a3f42d5d..d188fc5ef 100644
--- a/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java
+++ b/java/src/com/android/inputmethod/latin/SuggestionSpanPickedNotificationReceiver.java
@@ -23,7 +23,7 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
-public class SuggestionSpanPickedNotificationReceiver extends BroadcastReceiver {
+public final class SuggestionSpanPickedNotificationReceiver extends BroadcastReceiver {
private static final boolean DBG = LatinImeLogger.sDBG;
private static final String TAG =
SuggestionSpanPickedNotificationReceiver.class.getSimpleName();
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
index bdd988df2..8f21b7b4a 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -24,7 +24,7 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import java.util.ArrayList;
import java.util.Locale;
-public class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryDictionary {
+public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryDictionary {
private boolean mClosed;
public SynchronouslyLoadedContactsBinaryDictionary(final Context context, final Locale locale) {
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
index b8cfddd4e..612f54d73 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
@@ -23,7 +23,7 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import java.util.ArrayList;
-public class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionary {
+public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionary {
public SynchronouslyLoadedUserBinaryDictionary(final Context context, final String locale) {
this(context, locale, false);
diff --git a/java/src/com/android/inputmethod/latin/TargetApplicationGetter.java b/java/src/com/android/inputmethod/latin/TargetApplicationGetter.java
index 4265309e5..743a8c60f 100644
--- a/java/src/com/android/inputmethod/latin/TargetApplicationGetter.java
+++ b/java/src/com/android/inputmethod/latin/TargetApplicationGetter.java
@@ -22,8 +22,7 @@ import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.util.LruCache;
-public class TargetApplicationGetter extends AsyncTask {
-
+public final class TargetApplicationGetter extends AsyncTask {
private static final int MAX_CACHE_ENTRIES = 64; // arbitrary
private static LruCache sCache =
new LruCache(MAX_CACHE_ENTRIES);
@@ -32,6 +31,7 @@ public class TargetApplicationGetter extends AsyncTask
+ private static final class UpdateBinaryTask extends AsyncTask
implements BigramDictionaryInterface {
private final UserHistoryDictionaryBigramList mBigramList;
private final boolean mAddLevel0Bigrams;
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java
index bb0f5429a..df44948f9 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionaryBigramList.java
@@ -26,7 +26,7 @@ import java.util.Set;
* All bigrams including stale ones in SQL DB should be stored in this class to avoid adding stale
* bigrams when we write to the SQL DB.
*/
-public class UserHistoryDictionaryBigramList {
+public final class UserHistoryDictionaryBigramList {
public static final byte FORGETTING_CURVE_INITIAL_VALUE = 0;
private static final String TAG = UserHistoryDictionaryBigramList.class.getSimpleName();
private static final HashMap EMPTY_BIGRAM_MAP = CollectionUtils.newHashMap();
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryForgettingCurveUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryForgettingCurveUtils.java
index 3d3bd980c..9053d709b 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryForgettingCurveUtils.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryForgettingCurveUtils.java
@@ -36,7 +36,7 @@ public final class UserHistoryForgettingCurveUtils {
// This utility class is not publicly instantiable.
}
- public static class ForgettingCurveParams {
+ public static final class ForgettingCurveParams {
private byte mFc;
long mLastTouchedTime = 0;
private final boolean mIsValid;
@@ -195,7 +195,7 @@ public final class UserHistoryForgettingCurveUtils {
return (elapsedTime < ELAPSED_TIME_MAX - 1 || level > 0);
}
- private static class MathUtils {
+ private static final class MathUtils {
public static final int[][] SCORE_TABLE = new int[FC_LEVEL_MAX][ELAPSED_TIME_MAX + 1];
static {
for (int i = 0; i < FC_LEVEL_MAX; ++i) {
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 275ebf305..8a1bbed12 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -24,7 +24,7 @@ import java.util.Arrays;
/**
* A place to store the currently composing word with information such as adjacent key codes as well
*/
-public class WordComposer {
+public final class WordComposer {
private static final int N = BinaryDictionary.MAX_WORD_LENGTH;
public static final int CAPS_MODE_OFF = 0;
diff --git a/java/src/com/android/inputmethod/latin/WordListInfo.java b/java/src/com/android/inputmethod/latin/WordListInfo.java
index 54f04d78f..095320e25 100644
--- a/java/src/com/android/inputmethod/latin/WordListInfo.java
+++ b/java/src/com/android/inputmethod/latin/WordListInfo.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.latin;
/**
* Information container for a word list.
*/
-public class WordListInfo {
+public final class WordListInfo {
public final String mId;
public final String mLocale;
public WordListInfo(final String id, final String locale) {
diff --git a/java/src/com/android/inputmethod/latin/XmlParseUtils.java b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
index b5cbaf19e..75dc68f1d 100644
--- a/java/src/com/android/inputmethod/latin/XmlParseUtils.java
+++ b/java/src/com/android/inputmethod/latin/XmlParseUtils.java
@@ -36,28 +36,28 @@ public final class XmlParseUtils {
}
@SuppressWarnings("serial")
- public static class IllegalStartTag extends ParseException {
+ public static final class IllegalStartTag extends ParseException {
public IllegalStartTag(XmlPullParser parser, String parent) {
super("Illegal start tag " + parser.getName() + " in " + parent, parser);
}
}
@SuppressWarnings("serial")
- public static class IllegalEndTag extends ParseException {
+ public static final class IllegalEndTag extends ParseException {
public IllegalEndTag(XmlPullParser parser, String parent) {
super("Illegal end tag " + parser.getName() + " in " + parent, parser);
}
}
@SuppressWarnings("serial")
- public static class IllegalAttribute extends ParseException {
+ public static final class IllegalAttribute extends ParseException {
public IllegalAttribute(XmlPullParser parser, String attribute) {
super("Tag " + parser.getName() + " has illegal attribute " + attribute, parser);
}
}
@SuppressWarnings("serial")
- public static class NonEmptyTag extends ParseException{
+ public static final class NonEmptyTag extends ParseException{
public NonEmptyTag(String tag, XmlPullParser parser) {
super(tag + " must be empty tag", parser);
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index a1606db60..7b0231a6b 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -27,10 +27,10 @@ import java.util.ArrayList;
import java.util.Map;
import java.util.Stack;
-public class BinaryDictIOUtils {
+public final class BinaryDictIOUtils {
private static final boolean DBG = false;
- private static class Position {
+ private static final class Position {
public static final int NOT_READ_GROUPCOUNT = -1;
public int mAddress;
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 9fc694218..b431a4da9 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -43,7 +43,7 @@ import java.util.TreeMap;
*
* All the methods in this class are static.
*/
-public class BinaryDictInputOutput {
+public final class BinaryDictInputOutput {
private static final boolean DBG = MakedictLog.DBG;
@@ -124,7 +124,7 @@ public class BinaryDictInputOutput {
/**
* A class grouping utility function for our specific character encoding.
*/
- private static class CharEncoding {
+ private static final class CharEncoding {
private static final int MINIMAL_ONE_BYTE_CHARACTER_VALUE = 0x20;
private static final int MAXIMAL_ONE_BYTE_CHARACTER_VALUE = 0xFF;
diff --git a/java/src/com/android/inputmethod/latin/makedict/CharGroupInfo.java b/java/src/com/android/inputmethod/latin/makedict/CharGroupInfo.java
index ed9388409..8e64082e6 100644
--- a/java/src/com/android/inputmethod/latin/makedict/CharGroupInfo.java
+++ b/java/src/com/android/inputmethod/latin/makedict/CharGroupInfo.java
@@ -23,7 +23,7 @@ import java.util.ArrayList;
/**
* Raw char group info straight out of a file. This will contain numbers for addresses.
*/
-public class CharGroupInfo {
+public final class CharGroupInfo {
public final int mOriginalAddress;
public final int mEndAddress;
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 35311f0c2..b3fbb9fb5 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -221,7 +221,7 @@ public final class FormatSpec {
/**
* Options about file format.
*/
- public static class FormatOptions {
+ public static final class FormatOptions {
public final int mVersion;
public final boolean mSupportsDynamicUpdate;
public FormatOptions(final int version) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 98cf308c8..3193ef457 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -28,8 +28,7 @@ import java.util.LinkedList;
/**
* A dictionary that can fusion heads and tails of words for more compression.
*/
-public class FusionDictionary implements Iterable {
-
+public final class FusionDictionary implements Iterable {
private static final boolean DBG = MakedictLog.DBG;
/**
@@ -40,7 +39,7 @@ public class FusionDictionary implements Iterable {
* This class also contains fields to cache size and address, to help with binary
* generation.
*/
- public static class Node {
+ public static final class Node {
ArrayList mData;
// To help with binary generation
int mCachedSize = Integer.MIN_VALUE;
@@ -60,7 +59,7 @@ public class FusionDictionary implements Iterable {
*
* This represents an "attribute", that is either a bigram or a shortcut.
*/
- public static class WeightedString {
+ public static final class WeightedString {
public final String mWord;
public int mFrequency;
public WeightedString(String word, int frequency) {
@@ -94,7 +93,7 @@ public class FusionDictionary implements Iterable {
* value is the frequency of this terminal. A terminal may have non-null shortcuts and/or
* bigrams, but a non-terminal may not. Moreover, children, if present, are null.
*/
- public static class CharGroup {
+ public static final class CharGroup {
public static final int NOT_A_TERMINAL = -1;
final int mChars[];
ArrayList mShortcutTargets;
@@ -253,7 +252,7 @@ public class FusionDictionary implements Iterable {
*
* There are no options at the moment, so this class is empty.
*/
- public static class DictionaryOptions {
+ public static final class DictionaryOptions {
public final boolean mGermanUmlautProcessing;
public final boolean mFrenchLigatureProcessing;
public final HashMap mAttributes;
@@ -511,7 +510,7 @@ public class FusionDictionary implements Iterable {
* is ignored.
* This comparator imposes orderings that are inconsistent with equals.
*/
- static private class CharGroupComparator implements java.util.Comparator {
+ static private final class CharGroupComparator implements java.util.Comparator {
@Override
public int compare(CharGroup c1, CharGroup c2) {
if (c1.mChars[0] == c2.mChars[0]) return 0;
@@ -746,9 +745,8 @@ public class FusionDictionary implements Iterable {
*
* This is purely for convenience.
*/
- public static class DictionaryIterator implements Iterator {
-
- private static class Position {
+ public static final class DictionaryIterator implements Iterator {
+ private static final class Position {
public Iterator pos;
public int length;
public Position(ArrayList groups) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/MakedictLog.java b/java/src/com/android/inputmethod/latin/makedict/MakedictLog.java
index 3f0cd0796..6c6b00b6a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/MakedictLog.java
+++ b/java/src/com/android/inputmethod/latin/makedict/MakedictLog.java
@@ -21,7 +21,7 @@ import android.util.Log;
/**
* Wrapper to redirect log events to the right output medium.
*/
-public class MakedictLog {
+public final class MakedictLog {
public static final boolean DBG = false;
private static final String TAG = MakedictLog.class.getSimpleName();
diff --git a/java/src/com/android/inputmethod/latin/makedict/PendingAttribute.java b/java/src/com/android/inputmethod/latin/makedict/PendingAttribute.java
index 5b41d27f2..5bb24da74 100644
--- a/java/src/com/android/inputmethod/latin/makedict/PendingAttribute.java
+++ b/java/src/com/android/inputmethod/latin/makedict/PendingAttribute.java
@@ -22,7 +22,7 @@ package com.android.inputmethod.latin.makedict;
* An attribute is either a bigram or a shortcut.
* All instances of this class are always immutable.
*/
-public class PendingAttribute {
+public final class PendingAttribute {
public final int mFrequency;
public final int mAddress;
public PendingAttribute(final int frequency, final int address) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/UnsupportedFormatException.java b/java/src/com/android/inputmethod/latin/makedict/UnsupportedFormatException.java
index bd42fb8fa..dbb2ea870 100644
--- a/java/src/com/android/inputmethod/latin/makedict/UnsupportedFormatException.java
+++ b/java/src/com/android/inputmethod/latin/makedict/UnsupportedFormatException.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.latin.makedict;
/**
* Simple exception thrown when a file format is not recognized.
*/
-public class UnsupportedFormatException extends Exception {
+public final class UnsupportedFormatException extends Exception {
public UnsupportedFormatException(String description) {
super(description);
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/Word.java b/java/src/com/android/inputmethod/latin/makedict/Word.java
index 4683ef154..4c4f18f1a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/Word.java
+++ b/java/src/com/android/inputmethod/latin/makedict/Word.java
@@ -26,7 +26,7 @@ import java.util.Arrays;
*
* This is chiefly used to iterate a dictionary.
*/
-public class Word implements Comparable {
+public final class Word implements Comparable {
public final String mWord;
public final int mFrequency;
public final ArrayList mShortcutTargets;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index eef7a51f2..5a11ae534 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -50,7 +50,7 @@ import java.util.TreeMap;
/**
* Service for spell checking, using LatinIME's dictionaries and mechanisms.
*/
-public class AndroidSpellCheckerService extends SpellCheckerService
+public final class AndroidSpellCheckerService extends SpellCheckerService
implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = AndroidSpellCheckerService.class.getSimpleName();
private static final boolean DBG = false;
@@ -201,8 +201,8 @@ public class AndroidSpellCheckerService extends SpellCheckerService
}
// TODO: remove this class and replace it by storage local to the session.
- public static class SuggestionsGatherer {
- public static class Result {
+ public static final class SuggestionsGatherer {
+ public static final class Result {
public final String[] mSuggestions;
public final boolean mHasRecommendedSuggestions;
public Result(final String[] gatheredSuggestions,
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
index 5a1bd37f5..668e7a641 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
@@ -26,7 +26,7 @@ import com.android.inputmethod.latin.CollectionUtils;
import java.util.ArrayList;
-public class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheckerSession {
+public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheckerSession {
private static final String TAG = AndroidSpellCheckerSession.class.getSimpleName();
private static final boolean DBG = false;
private final static String[] EMPTY_STRING_ARRAY = new String[0];
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index d9b622a18..53ed4d3c3 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -50,7 +50,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
protected final SuggestionsCache mSuggestionsCache = new SuggestionsCache();
private final ContentObserver mObserver;
- private static class SuggestionsParams {
+ private static final class SuggestionsParams {
public final String[] mSuggestions;
public final int mFlags;
public SuggestionsParams(String[] suggestions, int flags) {
@@ -59,7 +59,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
}
}
- protected static class SuggestionsCache {
+ protected static final class SuggestionsCache {
private static final char CHAR_DELIMITER = '\uFFFC';
private static final int MAX_CACHE_SIZE = 50;
private final LruCache mUnigramSuggestionsInfoCache =
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java b/java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java
index 3dbbd40cd..9d7c61a33 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictAndProximity.java
@@ -22,7 +22,7 @@ import com.android.inputmethod.keyboard.ProximityInfo;
/**
* A simple container for both a Dictionary and a ProximityInfo.
*/
-public class DictAndProximity {
+public final class DictAndProximity {
public final Dictionary mDictionary;
public final ProximityInfo mProximityInfo;
public DictAndProximity(final Dictionary dictionary, final ProximityInfo proximityInfo) {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index 53aa6c719..1fb2bbb6a 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit;
* the client code, but may help with sloppy clients.
*/
@SuppressWarnings("serial")
-public class DictionaryPool extends LinkedBlockingQueue {
+public final class DictionaryPool extends LinkedBlockingQueue {
private final static String TAG = DictionaryPool.class.getSimpleName();
// How many seconds we wait for a dictionary to become available. Past this delay, we give up in
// fear some bug caused a deadlock, and reset the whole pool.
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
index fe5225ebd..11bb97031 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
@@ -22,7 +22,7 @@ import com.android.inputmethod.latin.Constants;
import java.util.TreeMap;
-public class SpellCheckerProximityInfo {
+public final class SpellCheckerProximityInfo {
/* public for test */
final public static int NUL = Constants.NOT_A_CODE;
@@ -53,7 +53,7 @@ public class SpellCheckerProximityInfo {
return result;
}
- private static class Latin {
+ private static final class Latin {
// This is a map from the code point to the index in the PROXIMITY array.
// At the time the native code to read the binary dictionary needs the proximity info be
// passed as a flat array spaced by MAX_PROXIMITY_CHARS_SIZE columns, one for each input
@@ -122,7 +122,7 @@ public class SpellCheckerProximityInfo {
}
}
- private static class Cyrillic {
+ private static final class Cyrillic {
final private static TreeMap INDICES = CollectionUtils.newTreeMap();
// TODO: The following table is solely based on the keyboard layout. Consult with Russian
// speakers on commonly misspelled words/letters.
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsActivity.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsActivity.java
index e14db8797..e63dff312 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsActivity.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsActivity.java
@@ -23,7 +23,7 @@ import android.preference.PreferenceActivity;
/**
* Spell checker preference screen.
*/
-public class SpellCheckerSettingsActivity extends PreferenceActivity {
+public final class SpellCheckerSettingsActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
index 7056874a1..ef5123d68 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
@@ -24,7 +24,7 @@ import com.android.inputmethod.latin.R;
/**
* Preference screen.
*/
-public class SpellCheckerSettingsFragment extends PreferenceFragment {
+public final class SpellCheckerSettingsFragment extends PreferenceFragment {
/**
* Empty constructor for fragment generation.
*/
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index 1f883aa60..e9bf0fac4 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -30,14 +30,14 @@ import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.Utils;
-public class MoreSuggestions extends Keyboard {
+public final class MoreSuggestions extends Keyboard {
public static final int SUGGESTION_CODE_BASE = 1024;
MoreSuggestions(final MoreSuggestionsParam params) {
super(params);
}
- private static class MoreSuggestionsParam extends KeyboardParams {
+ private static final class MoreSuggestionsParam extends KeyboardParams {
private final int[] mWidths = new int[SuggestionStripView.MAX_SUGGESTIONS];
private final int[] mRowNumbers = new int[SuggestionStripView.MAX_SUGGESTIONS];
private final int[] mColumnOrders = new int[SuggestionStripView.MAX_SUGGESTIONS];
@@ -163,7 +163,7 @@ public class MoreSuggestions extends Keyboard {
}
}
- public static class Builder extends KeyboardBuilder {
+ public static final class Builder extends KeyboardBuilder {
private final MoreSuggestionsView mPaneView;
private SuggestedWords mSuggestions;
private int mFromPos;
@@ -216,7 +216,7 @@ public class MoreSuggestions extends Keyboard {
}
}
- private static class Divider extends Key.Spacer {
+ private static final class Divider extends Key.Spacer {
private final Drawable mIcon;
public Divider(final KeyboardParams params, final Drawable icon, final int x,
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index 5b23d7f3c..9b9a35478 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -40,7 +40,7 @@ import com.android.inputmethod.latin.R;
* A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
* key presses and touch movements.
*/
-public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
+public final class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
private final int[] mCoordinates = new int[2];
final KeyDetector mModalPanelKeyDetector;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 9e8ab81b0..e926fa209 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -70,7 +70,7 @@ import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayList;
-public class SuggestionStripView extends RelativeLayout implements OnClickListener,
+public final class SuggestionStripView extends RelativeLayout implements OnClickListener,
OnLongClickListener {
public interface Listener {
public boolean addWordToUserDictionary(String word);
@@ -105,7 +105,7 @@ public class SuggestionStripView extends RelativeLayout implements OnClickListen
private final UiHandler mHandler = new UiHandler(this);
- private static class UiHandler extends StaticInnerHandlerWrapper {
+ private static final class UiHandler extends StaticInnerHandlerWrapper {
private static final int MSG_HIDE_PREVIEW = 0;
public UiHandler(SuggestionStripView outerInstance) {
@@ -131,7 +131,7 @@ public class SuggestionStripView extends RelativeLayout implements OnClickListen
}
}
- private static class SuggestionStripViewParams {
+ private static final class SuggestionStripViewParams {
private static final int DEFAULT_SUGGESTIONS_COUNT_IN_STRIP = 3;
private static final float DEFAULT_CENTER_SUGGESTION_PERCENTILE = 0.40f;
private static final int DEFAULT_MAX_MORE_SUGGESTIONS_ROW = 2;
--
cgit v1.2.3-83-g751a
From 7a7d117aa7e7157ed429d68c4797218476151d8d Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Fri, 28 Sep 2012 14:14:31 +0900
Subject: Ignore the broken file.
bug: 7249561
Change-Id: If001bf75ef12b4d342a77e54706c7fed90c89afb
---
java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
index 2cb29d310..e39011145 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
@@ -180,12 +180,14 @@ public final class UserHistoryDictIOUtils {
try {
BinaryDictIOUtils.readUnigramsAndBigramsBinary(buffer, unigrams, frequencies,
bigrams);
- addWordsFromWordMap(unigrams, frequencies, bigrams, dict);
} catch (IOException e) {
Log.e(TAG, "IO exception while reading file: " + e);
} catch (UnsupportedFormatException e) {
Log.e(TAG, "Unsupported format: " + e);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ Log.e(TAG, "ArrayIndexOutOfBoundsException while reading file: " + e);
}
+ addWordsFromWordMap(unigrams, frequencies, bigrams, dict);
}
/**
--
cgit v1.2.3-83-g751a
From f3aed3ea26b49cdf54e0b69c707ebd092ac45f97 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Fri, 28 Sep 2012 16:47:33 +0900
Subject: Add updateChildrenAddress.
Change-Id: Ic06a755d85612476e719e580469dc1cd9447286c
---
.../latin/makedict/BinaryDictIOUtils.java | 36 ++++++++++++++++++++++
.../latin/makedict/BinaryDictInputOutput.java | 7 ++---
2 files changed, 39 insertions(+), 4 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 7b0231a6b..c34d19d22 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.CharEncoding;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
@@ -279,4 +280,39 @@ public final class BinaryDictIOUtils {
putSInt24(buffer, parentOffset);
buffer.position(originalPosition);
}
+
+ private static void skipString(final FusionDictionaryBufferInterface buffer,
+ final boolean hasMultipleChars) {
+ if (hasMultipleChars) {
+ int character = CharEncoding.readChar(buffer);
+ while (character != FormatSpec.INVALID_CHARACTER) {
+ character = CharEncoding.readChar(buffer);
+ }
+ } else {
+ CharEncoding.readChar(buffer);
+ }
+ }
+
+ /**
+ * Update a children address in a CharGroup that is addressed by groupOriginAddress.
+ *
+ * @param buffer the buffer to write.
+ * @param groupOriginAddress the address of the group.
+ * @param newChildrenAddress the absolute address of the child.
+ * @param formatOptions file format options.
+ */
+ public static void updateChildrenAddress(final FusionDictionaryBufferInterface buffer,
+ final int groupOriginAddress, final int newChildrenAddress,
+ final FormatOptions formatOptions) {
+ final int originalPosition = buffer.position();
+ buffer.position(groupOriginAddress);
+ final int flags = buffer.readUnsignedByte();
+ final int parentAddress = BinaryDictInputOutput.readParentAddress(buffer, formatOptions);
+ skipString(buffer, (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
+ if ((FormatSpec.FLAG_IS_TERMINAL) != 0) buffer.readUnsignedByte();
+ final int childrenOffset = newChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS
+ ? FormatSpec.NO_CHILDREN_ADDRESS : newChildrenAddress - buffer.position();
+ putSInt24(buffer, childrenOffset);
+ buffer.position(originalPosition);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index b431a4da9..3e6965a17 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -124,8 +124,7 @@ public final class BinaryDictInputOutput {
/**
* A class grouping utility function for our specific character encoding.
*/
- private static final class CharEncoding {
-
+ static final class CharEncoding {
private static final int MINIMAL_ONE_BYTE_CHARACTER_VALUE = 0x20;
private static final int MAXIMAL_ONE_BYTE_CHARACTER_VALUE = 0xFF;
@@ -263,7 +262,7 @@ public final class BinaryDictInputOutput {
* @param buffer the buffer, positioned over an encoded character.
* @return the character code.
*/
- private static int readChar(final FusionDictionaryBufferInterface buffer) {
+ static int readChar(final FusionDictionaryBufferInterface buffer) {
int character = buffer.readUnsignedByte();
if (!fitsOnOneByte(character)) {
if (FormatSpec.GROUP_CHARACTERS_TERMINATOR == character) {
@@ -1219,7 +1218,7 @@ public final class BinaryDictInputOutput {
}
}
- private static int readParentAddress(final FusionDictionaryBufferInterface buffer,
+ static int readParentAddress(final FusionDictionaryBufferInterface buffer,
final FormatOptions formatOptions) {
if (supportsDynamicUpdate(formatOptions)) {
final int parentAddress = buffer.readUnsignedInt24();
--
cgit v1.2.3-83-g751a
From 58fe5a421f3334641209300c5bc60c0e6a842220 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Thu, 27 Sep 2012 19:01:17 +0900
Subject: Fix gesture detection algorithm
This change also
* Introduces adaptive gesture detecting threshold for time domain in addition to length domain.
* Tunes the parameters for detecting gesture after fast typing.
* Fixes a bug in dismissing gesture floating preview text.
* Cleanup debug messages
Bug: 7218902
Change-Id: Iafccd872c6efe0c3b5ae65fa40b04c80d9f139c7
---
.../inputmethod/keyboard/PointerTracker.java | 86 +++++------
.../keyboard/internal/GestureStroke.java | 166 +++++++++++++--------
.../internal/GestureStrokeWithPreviewPoints.java | 2 +-
.../com/android/inputmethod/latin/LatinIME.java | 47 ++++--
4 files changed, 172 insertions(+), 129 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 5248b8abb..100a9c618 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -168,8 +168,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private static long sLastLetterTypingUpTime;
private static final InputPointers sAggregratedPointers = new InputPointers(
GestureStroke.DEFAULT_CAPACITY);
- private static int sLastRecognitionPointSize = 0;
- private static long sLastRecognitionTime = 0;
+ private static int sLastRecognitionPointSize = 0; // synchronized using sAggregratedPointers
+ private static long sLastRecognitionTime = 0; // synchronized using sAggregratedPointers
// The position and time at which first down event occurred.
private long mDownTime;
@@ -306,9 +306,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
if (DEBUG_LISTENER) {
- Log.d(TAG, "onPress : " + KeyDetector.printableCode(key)
- + " ignoreModifier=" + ignoreModifierKey
- + " enabled=" + key.isEnabled());
+ Log.d(TAG, String.format("[%d] onPress : %s%s%s", mPointerId,
+ KeyDetector.printableCode(key),
+ ignoreModifierKey ? " ignoreModifier" : "",
+ key.isEnabled() ? "" : " disabled"));
}
if (ignoreModifierKey) {
return false;
@@ -331,10 +332,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
final boolean altersCode = key.altCodeWhileTyping() && mTimerProxy.isTypingState();
final int code = altersCode ? key.getAltCode() : primaryCode;
if (DEBUG_LISTENER) {
- Log.d(TAG, "onCodeInput: " + Keyboard.printableCode(code)
- + " text=" + key.getOutputText() + " x=" + x + " y=" + y
- + " ignoreModifier=" + ignoreModifierKey + " altersCode=" + altersCode
- + " enabled=" + key.isEnabled());
+ final String output = code == Keyboard.CODE_OUTPUT_TEXT
+ ? key.getOutputText() : Keyboard.printableCode(code);
+ Log.d(TAG, String.format("[%d] onCodeInput: %4d %4d %s%s%s", mPointerId, x, y,
+ output, ignoreModifierKey ? " ignoreModifier" : "",
+ altersCode ? " altersCode" : "", key.isEnabled() ? "" : " disabled"));
}
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.pointerTracker_callListenerOnCodeInput(key, x, y, ignoreModifierKey,
@@ -362,9 +364,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
if (DEBUG_LISTENER) {
- Log.d(TAG, "onRelease : " + Keyboard.printableCode(primaryCode)
- + " sliding=" + withSliding + " ignoreModifier=" + ignoreModifierKey
- + " enabled="+ key.isEnabled());
+ Log.d(TAG, String.format("[%d] onRelease : %s%s%s%s", mPointerId,
+ Keyboard.printableCode(primaryCode),
+ withSliding ? " sliding" : "", ignoreModifierKey ? " ignoreModifier" : "",
+ key.isEnabled() ? "": " disabled"));
}
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.pointerTracker_callListenerOnRelease(key, primaryCode, withSliding,
@@ -380,7 +383,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private void callListenerOnCancelInput() {
if (DEBUG_LISTENER) {
- Log.d(TAG, "onCancelInput");
+ Log.d(TAG, String.format("[%d] onCancelInput", mPointerId));
}
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.pointerTracker_callListenerOnCancelInput();
@@ -389,6 +392,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
private void setKeyDetectorInner(final KeyDetector keyDetector) {
+ final Keyboard keyboard = keyDetector.getKeyboard();
+ if (keyDetector == mKeyDetector && keyboard == mKeyboard) {
+ return;
+ }
mKeyDetector = keyDetector;
mKeyboard = keyDetector.getKeyboard();
mGestureStrokeWithPreviewPoints.setKeyboardGeometry(mKeyboard.mMostCommonKeyWidth);
@@ -551,10 +558,15 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return;
}
if (DEBUG_LISTENER) {
- Log.d(TAG, "onStartBatchInput");
+ Log.d(TAG, String.format("[%d] onStartBatchInput", mPointerId));
}
sInGesture = true;
- mListener.onStartBatchInput();
+ synchronized (sAggregratedPointers) {
+ sAggregratedPointers.reset();
+ sLastRecognitionPointSize = 0;
+ sLastRecognitionTime = 0;
+ mListener.onStartBatchInput();
+ }
final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
}
@@ -569,7 +581,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
sLastRecognitionPointSize = size;
sLastRecognitionTime = eventTime;
if (DEBUG_LISTENER) {
- Log.d(TAG, "onUpdateBatchInput: batchPoints=" + size);
+ Log.d(TAG, String.format("[%d] onUpdateBatchInput: batchPoints=%d",
+ mPointerId, size));
}
mListener.onUpdateBatchInput(sAggregratedPointers);
}
@@ -582,36 +595,19 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private void mayEndBatchInput() {
synchronized (sAggregratedPointers) {
mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregratedPointers);
- mGestureStrokeWithPreviewPoints.reset();
if (getActivePointerTrackerCount() == 1) {
if (DEBUG_LISTENER) {
- Log.d(TAG, "onEndBatchInput: batchPoints="
- + sAggregratedPointers.getPointerSize());
+ Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d",
+ mPointerId, sAggregratedPointers.getPointerSize()));
}
sInGesture = false;
mListener.onEndBatchInput(sAggregratedPointers);
- clearBatchInputPointsOfAllPointerTrackers();
}
}
final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
}
- private static void abortBatchInput() {
- clearBatchInputPointsOfAllPointerTrackers();
- }
-
- private static void clearBatchInputPointsOfAllPointerTrackers() {
- final int trackersSize = sTrackers.size();
- for (int i = 0; i < trackersSize; ++i) {
- final PointerTracker tracker = sTrackers.get(i);
- tracker.mGestureStrokeWithPreviewPoints.reset();
- }
- sAggregratedPointers.reset();
- sLastRecognitionPointSize = 0;
- sLastRecognitionTime = 0;
- }
-
public void processMotionEvent(final int action, final int x, final int y, final long eventTime,
final KeyEventHandler handler) {
switch (action) {
@@ -681,18 +677,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (getActivePointerTrackerCount() == 1) {
sGestureFirstDownTime = eventTime;
}
- onGestureDownEvent(x, y, eventTime);
+ mGestureStrokeWithPreviewPoints.onDownEvent(x, y, eventTime, sGestureFirstDownTime,
+ sLastLetterTypingUpTime);
}
}
- private void onGestureDownEvent(final int x, final int y, final long eventTime) {
- mIsDetectingGesture = true;
- mGestureStrokeWithPreviewPoints.setLastLetterTypingTime(eventTime, sLastLetterTypingUpTime);
- final int elapsedTimeFromFirstDown = (int)(eventTime - sGestureFirstDownTime);
- mGestureStrokeWithPreviewPoints.addPoint(x, y, elapsedTimeFromFirstDown,
- true /* isMajorEvent */);
- }
-
private void onDownEventInternal(final int x, final int y, final long eventTime) {
Key key = onDownKey(x, y, eventTime);
// Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
@@ -925,9 +914,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mayEndBatchInput();
return;
}
- // This event will be recognized as a regular code input. Clear unused possible batch points
- // so they are not mistakenly displayed as preview.
- clearBatchInputPointsOfAllPointerTrackers();
+
if (mKeyAlreadyProcessed) {
return;
}
@@ -941,7 +928,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
public void onShowMoreKeysPanel(final int x, final int y, final KeyEventHandler handler) {
- abortBatchInput();
onLongPressed();
mIsShowingMoreKeysPanel = true;
onDownEvent(x, y, SystemClock.uptimeMillis(), handler);
@@ -1029,7 +1015,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
final long eventTime) {
final Key key = mKeyDetector.detectHitKey(x, y);
final String code = KeyDetector.printableCode(key);
- Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %s", title,
- (mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, eventTime, code));
+ Log.d(TAG, String.format("[%d]%s%s %4d %4d %5d %s", mPointerId,
+ (mKeyAlreadyProcessed ? "-" : " "), title, x, y, eventTime, code));
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
index 9fe6fa3f8..c0e92df32 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java
@@ -22,6 +22,7 @@ import com.android.inputmethod.latin.ResizableIntArray;
public class GestureStroke {
private static final String TAG = GestureStroke.class.getSimpleName();
private static final boolean DEBUG = false;
+ private static final boolean DEBUG_SPEED = false;
public static final int DEFAULT_CAPACITY = 128;
@@ -29,42 +30,52 @@ public class GestureStroke {
private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
- private int mIncrementalRecognitionSize;
- private int mLastIncrementalBatchSize;
- private long mLastMajorEventTime;
- private int mLastMajorEventX;
- private int mLastMajorEventY;
- private boolean mAfterFastTyping;
- private int mKeyWidth;
- private int mStartGestureLengthThresholdAfterFastTyping; // pixel
- private int mStartGestureLengthThreshold; // pixel
- private int mMinGestureSamplingLength; // pixel
- private int mGestureRecognitionSpeedThreshold; // pixel / sec
+ private int mKeyWidth; // pixel
+ // Static threshold for starting gesture detection
private int mDetectFastMoveSpeedThreshold; // pixel /sec
private int mDetectFastMoveTime;
private int mDetectFastMoveX;
private int mDetectFastMoveY;
+ // Dynamic threshold for gesture after fast typing
+ private boolean mAfterFastTyping;
+ private int mGestureDynamicDistanceThresholdFrom; // pixel
+ private int mGestureDynamicDistanceThresholdTo; // pixel
+ // Variables for gesture sampling
+ private int mGestureSamplingMinimumDistance; // pixel
+ private long mLastMajorEventTime;
+ private int mLastMajorEventX;
+ private int mLastMajorEventY;
+ // Variables for gesture recognition
+ private int mGestureRecognitionSpeedThreshold; // pixel / sec
+ private int mIncrementalRecognitionSize;
+ private int mLastIncrementalBatchSize;
// TODO: Move some of these to resource.
- private static final int GESTURE_AFTER_FAST_TYPING_DURATION_THRESHOLD = 350; // msec
- private static final float START_GESTURE_LENGTH_THRESHOLD_AFTER_FAST_TYPING_RATIO_TO_KEY_WIDTH =
- 8.0f;
- private static final int START_GESTURE_LENGTH_THRESHOLD_DECAY_DURATION = 400; // msec
- private static final float START_GESTURE_LENGTH_THRESHOLD_RATIO_TO_KEY_WIDTH = 0.6f;
- private static final int START_GESTURE_DURATION_THRESHOLD = 70; // msec
- private static final int MIN_GESTURE_RECOGNITION_TIME = 100; // msec
- private static final float MIN_GESTURE_SAMPLING_RATIO_TO_KEY_WIDTH = 1.0f / 6.0f;
- private static final float GESTURE_RECOGNITION_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH =
- 5.5f; // keyWidth / sec
- private static final float DETECT_FAST_MOVE_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH =
- 5.0f; // keyWidth / sec
- private static final int MSEC_PER_SEC = 1000;
- public static final boolean hasRecognitionTimePast(
- final long currentTime, final long lastRecognitionTime) {
- return currentTime > lastRecognitionTime + MIN_GESTURE_RECOGNITION_TIME;
- }
+ // Static threshold for gesture after fast typing
+ public static final int GESTURE_STATIC_TIME_THRESHOLD_AFTER_FAST_TYPING = 350; // msec
+
+ // Static threshold for starting gesture detection
+ private static final float DETECT_FAST_MOVE_SPEED_THRESHOLD = 1.5f; // keyWidth / sec
+
+ // Dynamic threshold for gesture after fast typing
+ private static final int GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION = 450; // msec
+ // Time based threshold values
+ private static final int GESTURE_DYNAMIC_TIME_THRESHOLD_FROM = 300; // msec
+ private static final int GESTURE_DYNAMIC_TIME_THRESHOLD_TO = 20; // msec
+ // Distance based threshold values
+ private static final float GESTURE_DYNAMIC_DISTANCE_THRESHOLD_FROM = 6.0f; // keyWidth
+ private static final float GESTURE_DYNAMIC_DISTANCE_THRESHOLD_TO = 0.35f; // keyWidth
+
+ // Parameters for gesture sampling
+ private static final float GESTURE_SAMPLING_MINIMUM_DISTANCE = 1.0f / 6.0f; // keyWidth
+
+ // Parameters for gesture recognition
+ private static final int GESTURE_RECOGNITION_MINIMUM_TIME = 100; // msec
+ private static final float GESTURE_RECOGNITION_SPEED_THRESHOLD = 5.5f; // keyWidth / sec
+
+ private static final int MSEC_PER_SEC = 1000;
public GestureStroke(final int pointerId) {
mPointerId = pointerId;
@@ -73,41 +84,58 @@ public class GestureStroke {
public void setKeyboardGeometry(final int keyWidth) {
mKeyWidth = keyWidth;
// TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key?
- mStartGestureLengthThresholdAfterFastTyping = (int)(keyWidth
- * START_GESTURE_LENGTH_THRESHOLD_AFTER_FAST_TYPING_RATIO_TO_KEY_WIDTH);
- mStartGestureLengthThreshold =
- (int)(keyWidth * START_GESTURE_LENGTH_THRESHOLD_RATIO_TO_KEY_WIDTH);
- mMinGestureSamplingLength = (int)(keyWidth * MIN_GESTURE_SAMPLING_RATIO_TO_KEY_WIDTH);
+ mDetectFastMoveSpeedThreshold = (int)(keyWidth * DETECT_FAST_MOVE_SPEED_THRESHOLD);
+ mGestureDynamicDistanceThresholdFrom =
+ (int)(keyWidth * GESTURE_DYNAMIC_DISTANCE_THRESHOLD_FROM);
+ mGestureDynamicDistanceThresholdTo =
+ (int)(keyWidth * GESTURE_DYNAMIC_DISTANCE_THRESHOLD_TO);
+ mGestureSamplingMinimumDistance = (int)(keyWidth * GESTURE_SAMPLING_MINIMUM_DISTANCE);
mGestureRecognitionSpeedThreshold =
- (int)(keyWidth * GESTURE_RECOGNITION_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH);
- mDetectFastMoveSpeedThreshold =
- (int)(keyWidth * DETECT_FAST_MOVE_SPEED_THRESHOLD_RATIO_TO_KEY_WIDTH);
+ (int)(keyWidth * GESTURE_RECOGNITION_SPEED_THRESHOLD);
if (DEBUG) {
- Log.d(TAG, "[" + mPointerId + "] setKeyboardGeometry: keyWidth=" + keyWidth
- + " tL0=" + mStartGestureLengthThresholdAfterFastTyping
- + " tL=" + mStartGestureLengthThreshold);
+ Log.d(TAG, String.format(
+ "[%d] setKeyboardGeometry: keyWidth=%3d tT=%3d >> %3d tD=%3d >> %3d",
+ mPointerId, keyWidth,
+ GESTURE_DYNAMIC_TIME_THRESHOLD_FROM,
+ GESTURE_DYNAMIC_TIME_THRESHOLD_TO,
+ mGestureDynamicDistanceThresholdFrom,
+ mGestureDynamicDistanceThresholdTo));
}
}
- public void setLastLetterTypingTime(final long downTime, final long lastTypingTime) {
- final long elpasedTimeAfterTyping = downTime - lastTypingTime;
- if (elpasedTimeAfterTyping < GESTURE_AFTER_FAST_TYPING_DURATION_THRESHOLD) {
+ public void onDownEvent(final int x, final int y, final long downTime,
+ final long gestureFirstDownTime, final long lastTypingTime) {
+ reset();
+ final long elapsedTimeAfterTyping = downTime - lastTypingTime;
+ if (elapsedTimeAfterTyping < GESTURE_STATIC_TIME_THRESHOLD_AFTER_FAST_TYPING) {
mAfterFastTyping = true;
}
if (DEBUG) {
- Log.d(TAG, "[" + mPointerId + "] setLastTypingTime: dT=" + elpasedTimeAfterTyping
- + " afterFastTyping=" + mAfterFastTyping);
+ Log.d(TAG, String.format("[%d] onDownEvent: dT=%3d%s", mPointerId,
+ elapsedTimeAfterTyping, mAfterFastTyping ? " afterFastTyping" : ""));
}
+ final int elapsedTimeFromFirstDown = (int)(downTime - gestureFirstDownTime);
+ addPoint(x, y, elapsedTimeFromFirstDown, true /* isMajorEvent */);
}
- private int getStartGestureLengthThreshold(final int deltaTime) {
- if (!mAfterFastTyping || deltaTime >= START_GESTURE_LENGTH_THRESHOLD_DECAY_DURATION) {
- return mStartGestureLengthThreshold;
+ private int getGestureDynamicDistanceThreshold(final int deltaTime) {
+ if (!mAfterFastTyping || deltaTime >= GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION) {
+ return mGestureDynamicDistanceThresholdTo;
}
final int decayedThreshold =
- (mStartGestureLengthThresholdAfterFastTyping - mStartGestureLengthThreshold)
- * deltaTime / START_GESTURE_LENGTH_THRESHOLD_DECAY_DURATION;
- return mStartGestureLengthThresholdAfterFastTyping - decayedThreshold;
+ (mGestureDynamicDistanceThresholdFrom - mGestureDynamicDistanceThresholdTo)
+ * deltaTime / GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION;
+ return mGestureDynamicDistanceThresholdFrom - decayedThreshold;
+ }
+
+ private int getGestureDynamicTimeThreshold(final int deltaTime) {
+ if (!mAfterFastTyping || deltaTime >= GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION) {
+ return GESTURE_DYNAMIC_TIME_THRESHOLD_TO;
+ }
+ final int decayedThreshold =
+ (GESTURE_DYNAMIC_TIME_THRESHOLD_FROM - GESTURE_DYNAMIC_TIME_THRESHOLD_TO)
+ * deltaTime / GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION;
+ return GESTURE_DYNAMIC_TIME_THRESHOLD_FROM - decayedThreshold;
}
public boolean isStartOfAGesture() {
@@ -120,21 +148,24 @@ public class GestureStroke {
}
final int lastIndex = size - 1;
final int deltaTime = mEventTimes.get(lastIndex) - mDetectFastMoveTime;
- final int deltaLength = getDistance(
+ final int deltaDistance = getDistance(
mXCoordinates.get(lastIndex), mYCoordinates.get(lastIndex),
mDetectFastMoveX, mDetectFastMoveY);
- final int startGestureLengthThreshold = getStartGestureLengthThreshold(deltaTime);
- final boolean isStartOfAGesture = deltaTime > START_GESTURE_DURATION_THRESHOLD
- && deltaLength > startGestureLengthThreshold;
+ final int distanceThreshold = getGestureDynamicDistanceThreshold(deltaTime);
+ final int timeThreshold = getGestureDynamicTimeThreshold(deltaTime);
+ final boolean isStartOfAGesture = deltaTime >= timeThreshold
+ && deltaDistance >= distanceThreshold;
if (DEBUG) {
- Log.d(TAG, "[" + mPointerId + "] isStartOfAGesture: dT=" + deltaTime
- + " dL=" + deltaLength + " tL=" + startGestureLengthThreshold
- + " points=" + size + (isStartOfAGesture ? " Detect start of a gesture" : ""));
+ Log.d(TAG, String.format("[%d] isStartOfAGesture: dT=%3d tT=%3d dD=%3d tD=%3d%s%s",
+ mPointerId, deltaTime, timeThreshold,
+ deltaDistance, distanceThreshold,
+ mAfterFastTyping ? " afterFastTyping" : "",
+ isStartOfAGesture ? " startOfAGesture" : ""));
}
return isStartOfAGesture;
}
- public void reset() {
+ protected void reset() {
mIncrementalRecognitionSize = 0;
mLastIncrementalBatchSize = 0;
mEventTimes.setLength(0);
@@ -167,15 +198,17 @@ public class GestureStroke {
if (msecs > 0) {
final int pixels = getDistance(lastX, lastY, x, y);
final int pixelsPerSec = pixels * MSEC_PER_SEC;
- if (DEBUG) {
+ if (DEBUG_SPEED) {
final float speed = (float)pixelsPerSec / msecs / mKeyWidth;
- Log.d(TAG, String.format("[" + mPointerId + "] speed=%.3f", speed));
+ Log.d(TAG, String.format("[%d] detectFastMove: speed=%5.2f", mPointerId, speed));
}
// Equivalent to (pixels / msecs < mStartSpeedThreshold / MSEC_PER_SEC)
if (mDetectFastMoveTime == 0 && pixelsPerSec > mDetectFastMoveSpeedThreshold * msecs) {
if (DEBUG) {
- Log.d(TAG, "[" + mPointerId + "] detect fast move: T="
- + time + " points = " + size);
+ final float speed = (float)pixelsPerSec / msecs / mKeyWidth;
+ Log.d(TAG, String.format(
+ "[%d] detectFastMove: speed=%5.2f T=%3d points=%3d fastMove",
+ mPointerId, speed, time, size));
}
mDetectFastMoveTime = time;
mDetectFastMoveX = x;
@@ -192,8 +225,8 @@ public class GestureStroke {
appendPoint(x, y, time);
updateMajorEvent(x, y, time);
} else {
- final int dist = detectFastMove(x, y, time);
- if (dist > mMinGestureSamplingLength) {
+ final int distance = detectFastMove(x, y, time);
+ if (distance > mGestureSamplingMinimumDistance) {
appendPoint(x, y, time);
}
}
@@ -216,6 +249,11 @@ public class GestureStroke {
}
}
+ public static final boolean hasRecognitionTimePast(
+ final long currentTime, final long lastRecognitionTime) {
+ return currentTime > lastRecognitionTime + GESTURE_RECOGNITION_MINIMUM_TIME;
+ }
+
public void appendAllBatchPoints(final InputPointers out) {
appendBatchPoints(out, mEventTimes.getLength());
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
index 5b3f31805..05e0a2ec3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java
@@ -38,7 +38,7 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
}
@Override
- public void reset() {
+ protected void reset() {
super.reset();
mStrokeId++;
mLastPreviewSize = 0;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 3e893303f..268d36ad2 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1402,6 +1402,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
@Override
public void onStartBatchInput() {
+ BatchInputUpdater.getInstance().onStartBatchInput();
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
if (ProductionFlag.IS_INTERNAL) {
@@ -1433,6 +1434,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private static final class BatchInputUpdater implements Handler.Callback {
private final Handler mHandler;
private LatinIME mLatinIme;
+ private boolean mInBatchInput; // synchornized using "this".
private BatchInputUpdater() {
final HandlerThread handlerThread = new HandlerThread(
@@ -1456,17 +1458,32 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
public boolean handleMessage(final Message msg) {
switch (msg.what) {
case MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
- final SuggestedWords suggestedWords = getSuggestedWordsGesture(
- (InputPointers)msg.obj, mLatinIme);
- showGesturePreviewAndSuggestionStrip(
- suggestedWords, false /* dismissGestureFloatingPreviewText */, mLatinIme);
+ updateBatchInput((InputPointers)msg.obj, mLatinIme);
break;
}
return true;
}
- public void updateGesturePreviewAndSuggestionStrip(final InputPointers batchPointers,
+ // Run in the UI thread.
+ public synchronized void onStartBatchInput() {
+ mInBatchInput = true;
+ }
+
+ // Run in the Handler thread.
+ private synchronized void updateBatchInput(final InputPointers batchPointers,
final LatinIME latinIme) {
+ if (!mInBatchInput) {
+ // Batch input has ended while the message was being delivered.
+ return;
+ }
+ final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(
+ batchPointers, latinIme);
+ latinIme.mHandler.showGesturePreviewAndSuggestionStrip(
+ suggestedWords, false /* dismissGestureFloatingPreviewText */);
+ }
+
+ // Run in the UI thread.
+ public void onUpdateBatchInput(final InputPointers batchPointers, final LatinIME latinIme) {
mLatinIme = latinIme;
if (mHandler.hasMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP)) {
return;
@@ -1476,15 +1493,20 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
.sendToTarget();
}
- public void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
- final boolean dismissGestureFloatingPreviewText, final LatinIME latinIme) {
+ // Run in the UI thread.
+ public synchronized SuggestedWords onEndBatchInput(final InputPointers batchPointers,
+ final LatinIME latinIme) {
+ mInBatchInput = false;
+ final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(
+ batchPointers, latinIme);
latinIme.mHandler.showGesturePreviewAndSuggestionStrip(
- suggestedWords, dismissGestureFloatingPreviewText);
+ suggestedWords, true /* dismissGestureFloatingPreviewText */);
+ return suggestedWords;
}
// {@link LatinIME#getSuggestedWords(int)} method calls with same session id have to
// be synchronized.
- public synchronized SuggestedWords getSuggestedWordsGesture(
+ private static SuggestedWords getSuggestedWordsGestureLocked(
final InputPointers batchPointers, final LatinIME latinIme) {
latinIme.mWordComposer.setBatchInputPointers(batchPointers);
return latinIme.getSuggestedWords(Suggest.SESSION_GESTURE);
@@ -1505,16 +1527,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
@Override
public void onUpdateBatchInput(final InputPointers batchPointers) {
- BatchInputUpdater.getInstance().updateGesturePreviewAndSuggestionStrip(batchPointers, this);
+ BatchInputUpdater.getInstance().onUpdateBatchInput(batchPointers, this);
}
@Override
public void onEndBatchInput(final InputPointers batchPointers) {
- final BatchInputUpdater batchInputUpdater = BatchInputUpdater.getInstance();
- final SuggestedWords suggestedWords = batchInputUpdater.getSuggestedWordsGesture(
+ final SuggestedWords suggestedWords = BatchInputUpdater.getInstance().onEndBatchInput(
batchPointers, this);
- batchInputUpdater.showGesturePreviewAndSuggestionStrip(
- suggestedWords, true /* dismissGestureFloatingPreviewText */, this);
final String batchInputText = (suggestedWords.size() > 0)
? suggestedWords.getWord(0) : null;
if (TextUtils.isEmpty(batchInputText)) {
--
cgit v1.2.3-83-g751a
From 7339a62a1368b632c0cedaf1d876a0e8590a47ed Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Mon, 1 Oct 2012 14:26:38 +0900
Subject: Fix NPE observed only by monkey test
Bug: 7258660
Change-Id: I286c704b32efeada8505d953438f2595166f7e8f
---
.../latin/suggestions/MoreSuggestions.java | 9 ++--
.../latin/suggestions/SuggestionStripView.java | 59 ++++++++++++----------
2 files changed, 35 insertions(+), 33 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index e9bf0fac4..4ad82abdd 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -22,7 +22,6 @@ import android.graphics.drawable.Drawable;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
@@ -175,11 +174,11 @@ public final class MoreSuggestions extends Keyboard {
}
public Builder layout(final SuggestedWords suggestions, final int fromPos,
- final int maxWidth, final int minWidth, final int maxRow) {
- final Keyboard keyboard = KeyboardSwitcher.getInstance().getKeyboard();
+ final int maxWidth, final int minWidth, final int maxRow,
+ final Keyboard parentKeyboard) {
final int xmlId = R.xml.kbd_suggestions_pane_template;
- load(xmlId, keyboard.mId);
- mParams.mVerticalGap = mParams.mTopPadding = keyboard.mVerticalGap / 2;
+ load(xmlId, parentKeyboard.mId);
+ mParams.mVerticalGap = mParams.mTopPadding = parentKeyboard.mVerticalGap / 2;
final int count = mParams.layout(suggestions, fromPos, maxWidth, minWidth, maxRow,
mPaneView);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index e926fa209..94283f242 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -52,7 +52,9 @@ import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
+import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.KeyboardView;
import com.android.inputmethod.keyboard.MoreKeysPanel;
import com.android.inputmethod.keyboard.PointerTracker;
@@ -751,36 +753,37 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
private boolean showMoreSuggestions() {
+ final Keyboard parentKeyboard = KeyboardSwitcher.getInstance().getKeyboard();
+ if (parentKeyboard == null) {
+ return false;
+ }
final SuggestionStripViewParams params = mParams;
- if (params.mMoreSuggestionsAvailable) {
- final int stripWidth = getWidth();
- final View container = mMoreSuggestionsContainer;
- final int maxWidth = stripWidth - container.getPaddingLeft()
- - container.getPaddingRight();
- final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder;
- builder.layout(mSuggestedWords, params.mSuggestionsCountInStrip, maxWidth,
- (int)(maxWidth * params.mMinMoreSuggestionsWidth),
- params.getMaxMoreSuggestionsRow());
- mMoreSuggestionsView.setKeyboard(builder.build());
- container.measure(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-
- final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView;
- final int pointX = stripWidth / 2;
- final int pointY = -params.mMoreSuggestionsBottomGap;
- moreKeysPanel.showMoreKeysPanel(
- this, mMoreSuggestionsController, pointX, pointY,
- mMoreSuggestionsWindow, mMoreSuggestionsListener);
- mMoreSuggestionsMode = MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING;
- mOriginX = mLastX;
- mOriginY = mLastY;
- mKeyboardView.dimEntireKeyboard(true);
- for (int i = 0; i < params.mSuggestionsCountInStrip; i++) {
- mWords.get(i).setPressed(false);
- }
- return true;
+ if (!params.mMoreSuggestionsAvailable) {
+ return false;
}
- return false;
+ final int stripWidth = getWidth();
+ final View container = mMoreSuggestionsContainer;
+ final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight();
+ final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder;
+ builder.layout(mSuggestedWords, params.mSuggestionsCountInStrip, maxWidth,
+ (int)(maxWidth * params.mMinMoreSuggestionsWidth),
+ params.getMaxMoreSuggestionsRow(), parentKeyboard);
+ mMoreSuggestionsView.setKeyboard(builder.build());
+ container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ final MoreKeysPanel moreKeysPanel = mMoreSuggestionsView;
+ final int pointX = stripWidth / 2;
+ final int pointY = -params.mMoreSuggestionsBottomGap;
+ moreKeysPanel.showMoreKeysPanel(this, mMoreSuggestionsController, pointX, pointY,
+ mMoreSuggestionsWindow, mMoreSuggestionsListener);
+ mMoreSuggestionsMode = MORE_SUGGESTIONS_CHECKING_MODAL_OR_SLIDING;
+ mOriginX = mLastX;
+ mOriginY = mLastY;
+ mKeyboardView.dimEntireKeyboard(true);
+ for (int i = 0; i < params.mSuggestionsCountInStrip; i++) {
+ mWords.get(i).setPressed(false);
+ }
+ return true;
}
// Working variables for onLongClick and dispatchTouchEvent.
--
cgit v1.2.3-83-g751a
From 574b80aacee95df26e85e6b78876a73d7076a672 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 1 Oct 2012 16:03:21 +0900
Subject: Remove debug prints.
Bug: 7226098
Change-Id: Ibacb740022a6af56c9d555d6797dd402a89f6ca4
---
.../com/android/inputmethod/latin/LatinIME.java | 4 ++++
.../inputmethod/latin/RichInputConnection.java | 25 +++++++++++-----------
2 files changed, 17 insertions(+), 12 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 268d36ad2..311355374 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1878,6 +1878,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mIsAutoCorrectionIndicatorOn = newAutoCorrectionIndicator;
final CharSequence textWithUnderline =
getTextWithUnderline(mWordComposer.getTypedWord());
+ // TODO: when called from an updateSuggestionStrip() call that results from a posted
+ // message, this is called outside any batch edit. Potentially, this may result in some
+ // janky flickering of the screen, although the display speed makes it unlikely in
+ // the practice.
mConnection.setComposingText(textWithUnderline, 1);
}
}
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 1acca5860..b27db579f 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -45,6 +45,7 @@ public final class RichInputConnection {
private static final String TAG = RichInputConnection.class.getSimpleName();
private static final boolean DBG = false;
private static final boolean DEBUG_PREVIOUS_TEXT = false;
+ private static final boolean DEBUG_BATCH_NESTING = false;
// Provision for a long word pair and a separator
private static final int LOOKBACK_CHARACTER_NUM = BinaryDictionary.MAX_WORD_LENGTH * 2 + 1;
private static final Pattern spaceRegex = Pattern.compile("\\s+");
@@ -128,7 +129,7 @@ public final class RichInputConnection {
Log.e(TAG, "Nest level too deep : " + mNestLevel);
}
}
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
@@ -163,7 +164,7 @@ public final class RichInputConnection {
}
public void finishComposingText() {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCommittedTextBeforeComposingText.append(mComposingText);
mCurrentCursorPosition += mComposingText.length();
@@ -177,7 +178,7 @@ public final class RichInputConnection {
}
public void commitText(final CharSequence text, final int i) {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCommittedTextBeforeComposingText.append(text);
mCurrentCursorPosition += text.length() - mComposingText.length();
@@ -247,7 +248,7 @@ public final class RichInputConnection {
}
public void deleteSurroundingText(final int i, final int j) {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
final int remainingChars = mComposingText.length() - i;
if (remainingChars >= 0) {
mComposingText.setLength(remainingChars);
@@ -283,7 +284,7 @@ public final class RichInputConnection {
}
public void sendKeyEvent(final KeyEvent keyEvent) {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
// This method is only called for enter or backspace when speaking to old
@@ -331,7 +332,7 @@ public final class RichInputConnection {
}
public void setComposingText(final CharSequence text, final int i) {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
mCurrentCursorPosition += text.length() - mComposingText.length();
mComposingText.setLength(0);
@@ -347,7 +348,7 @@ public final class RichInputConnection {
}
public void setSelection(final int from, final int to) {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
if (null != mIC) {
mIC.setSelection(from, to);
@@ -361,7 +362,7 @@ public final class RichInputConnection {
}
public void commitCorrection(final CorrectionInfo correctionInfo) {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
// This has no effect on the text field and does not change its content. It only makes
// TextView flash the text for a second based on indices contained in the argument.
@@ -375,7 +376,7 @@ public final class RichInputConnection {
}
public void commitCompletion(final CompletionInfo completionInfo) {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
final CharSequence text = completionInfo.getText();
mCommittedTextBeforeComposingText.append(text);
@@ -575,7 +576,7 @@ public final class RichInputConnection {
}
public void removeTrailingSpace() {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
final CharSequence lastOne = getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == Keyboard.CODE_SPACE) {
@@ -631,7 +632,7 @@ public final class RichInputConnection {
}
public boolean revertDoubleSpace() {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
// Here we test whether we indeed have a period and a space before us. This should not
// be needed, but it's there just in case something went wrong.
final CharSequence textBeforeCursor = getTextBeforeCursor(2, 0);
@@ -649,7 +650,7 @@ public final class RichInputConnection {
}
public boolean revertSwapPunctuation() {
- checkBatchEdit();
+ if (DEBUG_BATCH_NESTING) checkBatchEdit();
// Here we test whether we indeed have a space and something else before us. This should not
// be needed, but it's there just in case something went wrong.
final CharSequence textBeforeCursor = getTextBeforeCursor(2, 0);
--
cgit v1.2.3-83-g751a
From fb7e08ea8f40ebb4ac57e443f837043e7b57fd87 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Fri, 28 Sep 2012 17:03:23 +0900
Subject: Add writeCharGroup.
bug: 6669677
Change-Id: I36792ba9c511a5148c963096cc93ca8c2e0ee04e
---
.../latin/makedict/BinaryDictIOUtils.java | 127 ++++++++++++++++++++-
.../latin/makedict/BinaryDictInputOutput.java | 9 +-
2 files changed, 129 insertions(+), 7 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index c34d19d22..5c6417b04 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -22,9 +22,13 @@ import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictio
import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Stack;
@@ -251,7 +255,7 @@ public final class BinaryDictIOUtils {
buffer.put((byte)newFlags);
}
- private static void putSInt24(final FusionDictionaryBufferInterface buffer,
+ private static void writeSInt24ToBuffer(final FusionDictionaryBufferInterface buffer,
final int value) {
final int absValue = Math.abs(value);
buffer.put((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
@@ -259,6 +263,32 @@ public final class BinaryDictIOUtils {
buffer.put((byte)(absValue & 0xFF));
}
+ private static void writeSInt24ToStream(final OutputStream destination, final int value)
+ throws IOException {
+ final int absValue = Math.abs(value);
+ destination.write((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
+ destination.write((byte)((absValue >> 8) & 0xFF));
+ destination.write((byte)(absValue & 0xFF));
+ }
+
+ private static void writeVariableAddress(final OutputStream destination, final int value)
+ throws IOException {
+ switch (BinaryDictInputOutput.getByteSize(value)) {
+ case 1:
+ destination.write((byte)value);
+ break;
+ case 2:
+ destination.write((byte)(0xFF & (value >> 8)));
+ destination.write((byte)(0xFF & value));
+ break;
+ case 3:
+ destination.write((byte)(0xFF & (value >> 16)));
+ destination.write((byte)(0xFF & (value >> 8)));
+ destination.write((byte)(0xFF & value));
+ break;
+ }
+ }
+
/**
* Update a parent address in a CharGroup that is addressed by groupOriginAddress.
*
@@ -277,7 +307,7 @@ public final class BinaryDictIOUtils {
}
final int flags = buffer.readUnsignedByte();
final int parentOffset = newParentAddress - groupOriginAddress;
- putSInt24(buffer, parentOffset);
+ writeSInt24ToBuffer(buffer, parentOffset);
buffer.position(originalPosition);
}
@@ -293,6 +323,22 @@ public final class BinaryDictIOUtils {
}
}
+ private static void writeString(final OutputStream destination, final String word)
+ throws IOException {
+ final int length = word.length();
+ for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
+ final int codePoint = word.codePointAt(i);
+ if (CharEncoding.getCharSize(codePoint) == 1) {
+ destination.write((byte)codePoint);
+ } else {
+ destination.write((byte)(0xFF & (codePoint >> 16)));
+ destination.write((byte)(0xFF & (codePoint >> 8)));
+ destination.write((byte)(0xFF & codePoint));
+ }
+ }
+ destination.write((byte)FormatSpec.GROUP_CHARACTERS_TERMINATOR);
+ }
+
/**
* Update a children address in a CharGroup that is addressed by groupOriginAddress.
*
@@ -312,7 +358,82 @@ public final class BinaryDictIOUtils {
if ((FormatSpec.FLAG_IS_TERMINAL) != 0) buffer.readUnsignedByte();
final int childrenOffset = newChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS
? FormatSpec.NO_CHILDREN_ADDRESS : newChildrenAddress - buffer.position();
- putSInt24(buffer, childrenOffset);
+ writeSInt24ToBuffer(buffer, childrenOffset);
buffer.position(originalPosition);
}
+
+ /**
+ * Write a char group to an output stream.
+ * A char group is an in-memory representation of a node in trie.
+ * A char group info is an on-disk representation of a node.
+ *
+ * @param destination the stream to write.
+ * @param info the char group info to be written.
+ */
+ public static void writeCharGroup(final OutputStream destination, final CharGroupInfo info)
+ throws IOException {
+ destination.write((byte)info.mFlags);
+ final int parentOffset = info.mParentAddress == FormatSpec.NO_PARENT_ADDRESS ?
+ FormatSpec.NO_PARENT_ADDRESS : info.mParentAddress - info.mOriginalAddress;
+ writeSInt24ToStream(destination, parentOffset);
+
+ for (int i = 0; i < info.mCharacters.length; ++i) {
+ if (CharEncoding.getCharSize(info.mCharacters[i]) == 1) {
+ destination.write((byte)info.mCharacters[i]);
+ } else {
+ writeSInt24ToStream(destination, info.mCharacters[i]);
+ }
+ }
+ if (info.mCharacters.length > 1) {
+ destination.write((byte)FormatSpec.GROUP_CHARACTERS_TERMINATOR);
+ }
+
+ if ((info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0) {
+ destination.write((byte)info.mFrequency);
+ }
+
+ final int childrenOffset = info.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS ?
+ 0 : info.mChildrenAddress - info.mOriginalAddress;
+ writeSInt24ToStream(destination, childrenOffset);
+
+ if (info.mShortcutTargets != null && info.mShortcutTargets.size() > 0) {
+ final int shortcutListSize =
+ BinaryDictInputOutput.getShortcutListSize(info.mShortcutTargets);
+ destination.write((byte)(shortcutListSize >> 8));
+ destination.write((byte)(shortcutListSize & 0xFF));
+ final Iterator shortcutIterator = info.mShortcutTargets.iterator();
+ while (shortcutIterator.hasNext()) {
+ final WeightedString target = shortcutIterator.next();
+ destination.write((byte)BinaryDictInputOutput.makeShortcutFlags(
+ shortcutIterator.hasNext(), target.mFrequency));
+ writeString(destination, target.mWord);
+ }
+ }
+
+ if (info.mBigrams != null) {
+ // TODO: Consolidate this code with the code that computes the size of the bigram list
+ // in BinaryDictionaryInputOutput#computeActualNodeSize
+ for (int i = 0; i < info.mBigrams.size(); ++i) {
+ final int bigramOffset = info.mBigrams.get(i).mAddress - info.mOriginalAddress;
+ final int bigramFrequency = info.mBigrams.get(i).mFrequency;
+ int bigramFlags = (i < info.mBigrams.size() - 1)
+ ? FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT : 0;
+ bigramFlags |= (bigramOffset < 0) ? FormatSpec.FLAG_ATTRIBUTE_OFFSET_NEGATIVE : 0;
+ switch (BinaryDictInputOutput.getByteSize(bigramOffset)) {
+ case 1:
+ bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE;
+ break;
+ case 2:
+ bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES;
+ break;
+ case 3:
+ bigramFlags |= FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES;
+ break;
+ }
+ bigramFlags |= bigramFrequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY;
+ destination.write((byte)bigramFlags);
+ writeVariableAddress(destination, Math.abs(bigramOffset));
+ }
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 3e6965a17..ba29523c8 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -153,7 +153,7 @@ public final class BinaryDictInputOutput {
* @param character the character code.
* @return the size in binary encoded-form, either 1 or 3 bytes.
*/
- private static int getCharSize(final int character) {
+ static int getCharSize(final int character) {
// See char encoding in FusionDictionary.java
if (fitsOnOneByte(character)) return 1;
if (FormatSpec.INVALID_CHARACTER == character) return 1;
@@ -337,7 +337,7 @@ public final class BinaryDictInputOutput {
* This is known in advance and does not change according to position in the file
* like address lists do.
*/
- private static int getShortcutListSize(final ArrayList shortcutList) {
+ static int getShortcutListSize(final ArrayList shortcutList) {
if (null == shortcutList) return 0;
int size = FormatSpec.GROUP_SHORTCUT_LIST_SIZE_SIZE;
for (final WeightedString shortcut : shortcutList) {
@@ -438,7 +438,7 @@ public final class BinaryDictInputOutput {
* @param address the address
* @return the byte size.
*/
- private static int getByteSize(final int address) {
+ static int getByteSize(final int address) {
assert(address <= UINT24_MAX);
if (!hasChildrenAddress(address)) {
return 0;
@@ -858,7 +858,7 @@ public final class BinaryDictInputOutput {
* @param frequency the frequency of the attribute, 0..15
* @return the flags
*/
- private static final int makeShortcutFlags(final boolean more, final int frequency) {
+ static final int makeShortcutFlags(final boolean more, final int frequency) {
return (more ? FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT : 0)
+ (frequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY);
}
@@ -896,6 +896,7 @@ public final class BinaryDictInputOutput {
*/
private static int writePlacedNode(final FusionDictionary dict, byte[] buffer,
final Node node, final FormatOptions formatOptions) {
+ // TODO: Make the code in common with BinaryDictIOUtils#writeCharGroup
int index = node.mCachedAddress;
final int groupCount = node.mData.size();
--
cgit v1.2.3-83-g751a
From 7f438aa12f683ac15c8c8e60ca852412d00128db Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Mon, 1 Oct 2012 17:29:30 +0900
Subject: Make writeCharGroup return a size of a new group.
bug: 6669677
Change-Id: I56f6a07b04b08443f2c052927404318c2018fc9d
---
.../latin/makedict/BinaryDictIOUtils.java | 52 ++++++++++++++++++----
1 file changed, 43 insertions(+), 9 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 5c6417b04..5ed910c50 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -255,23 +255,34 @@ public final class BinaryDictIOUtils {
buffer.put((byte)newFlags);
}
- private static void writeSInt24ToBuffer(final FusionDictionaryBufferInterface buffer,
+ /**
+ * @return the size written, in bytes. Always 3 bytes.
+ */
+ private static int writeSInt24ToBuffer(final FusionDictionaryBufferInterface buffer,
final int value) {
final int absValue = Math.abs(value);
buffer.put((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
buffer.put((byte)((absValue >> 8) & 0xFF));
buffer.put((byte)(absValue & 0xFF));
+ return 3;
}
- private static void writeSInt24ToStream(final OutputStream destination, final int value)
+ /**
+ * @return the size written, in bytes. Always 3 bytes.
+ */
+ private static int writeSInt24ToStream(final OutputStream destination, final int value)
throws IOException {
final int absValue = Math.abs(value);
destination.write((byte)(((value < 0 ? 0x80 : 0) | (absValue >> 16)) & 0xFF));
destination.write((byte)((absValue >> 8) & 0xFF));
destination.write((byte)(absValue & 0xFF));
+ return 3;
}
- private static void writeVariableAddress(final OutputStream destination, final int value)
+ /**
+ * @return the size written, in bytes. 1, 2, or 3 bytes.
+ */
+ private static int writeVariableAddress(final OutputStream destination, final int value)
throws IOException {
switch (BinaryDictInputOutput.getByteSize(value)) {
case 1:
@@ -287,6 +298,7 @@ public final class BinaryDictIOUtils {
destination.write((byte)(0xFF & value));
break;
}
+ return BinaryDictInputOutput.getByteSize(value);
}
/**
@@ -323,20 +335,33 @@ public final class BinaryDictIOUtils {
}
}
- private static void writeString(final OutputStream destination, final String word)
+ /**
+ * Write a string to a stream.
+ *
+ * @param destination the stream to write.
+ * @param word the string to be written.
+ * @return the size written, in bytes.
+ * @throws IOException
+ */
+ private static int writeString(final OutputStream destination, final String word)
throws IOException {
+ int size = 0;
final int length = word.length();
for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
final int codePoint = word.codePointAt(i);
if (CharEncoding.getCharSize(codePoint) == 1) {
destination.write((byte)codePoint);
+ size++;
} else {
destination.write((byte)(0xFF & (codePoint >> 16)));
destination.write((byte)(0xFF & (codePoint >> 8)));
destination.write((byte)(0xFF & codePoint));
+ size += 3;
}
}
destination.write((byte)FormatSpec.GROUP_CHARACTERS_TERMINATOR);
+ size++;
+ return size;
}
/**
@@ -369,27 +394,32 @@ public final class BinaryDictIOUtils {
*
* @param destination the stream to write.
* @param info the char group info to be written.
+ * @return the size written, in bytes.
*/
- public static void writeCharGroup(final OutputStream destination, final CharGroupInfo info)
+ public static int writeCharGroup(final OutputStream destination, final CharGroupInfo info)
throws IOException {
+ int size = 1;
destination.write((byte)info.mFlags);
final int parentOffset = info.mParentAddress == FormatSpec.NO_PARENT_ADDRESS ?
FormatSpec.NO_PARENT_ADDRESS : info.mParentAddress - info.mOriginalAddress;
- writeSInt24ToStream(destination, parentOffset);
+ size += writeSInt24ToStream(destination, parentOffset);
for (int i = 0; i < info.mCharacters.length; ++i) {
if (CharEncoding.getCharSize(info.mCharacters[i]) == 1) {
destination.write((byte)info.mCharacters[i]);
+ size++;
} else {
- writeSInt24ToStream(destination, info.mCharacters[i]);
+ size += writeSInt24ToStream(destination, info.mCharacters[i]);
}
}
if (info.mCharacters.length > 1) {
destination.write((byte)FormatSpec.GROUP_CHARACTERS_TERMINATOR);
+ size++;
}
if ((info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0) {
destination.write((byte)info.mFrequency);
+ size++;
}
final int childrenOffset = info.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS ?
@@ -401,12 +431,14 @@ public final class BinaryDictIOUtils {
BinaryDictInputOutput.getShortcutListSize(info.mShortcutTargets);
destination.write((byte)(shortcutListSize >> 8));
destination.write((byte)(shortcutListSize & 0xFF));
+ size += 2;
final Iterator shortcutIterator = info.mShortcutTargets.iterator();
while (shortcutIterator.hasNext()) {
final WeightedString target = shortcutIterator.next();
destination.write((byte)BinaryDictInputOutput.makeShortcutFlags(
shortcutIterator.hasNext(), target.mFrequency));
- writeString(destination, target.mWord);
+ size++;
+ size += writeString(destination, target.mWord);
}
}
@@ -432,8 +464,10 @@ public final class BinaryDictIOUtils {
}
bigramFlags |= bigramFrequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY;
destination.write((byte)bigramFlags);
- writeVariableAddress(destination, Math.abs(bigramOffset));
+ size++;
+ size += writeVariableAddress(destination, Math.abs(bigramOffset));
}
}
+ return size;
}
}
--
cgit v1.2.3-83-g751a
From 15281adbc1580262888aba6fc73bbbe7fa9e0de8 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Tue, 2 Oct 2012 10:30:03 +0900
Subject: Show gesture floating preview text by default
Bug: 7244214
Change-Id: Ib4ab810ef50798828dd10c39a8077466165772e4
---
java/res/xml/prefs.xml | 4 ++--
.../com/android/inputmethod/keyboard/KeyboardView.java | 15 +++++++++++++--
java/src/com/android/inputmethod/latin/Settings.java | 8 ++++----
.../src/com/android/inputmethod/latin/SettingsValues.java | 2 +-
4 files changed, 20 insertions(+), 9 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index fe82b327c..9172b2415 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -88,11 +88,11 @@
android:persistent="true"
android:defaultValue="true" />
+ android:defaultValue="true" />
Date: Tue, 2 Oct 2012 17:09:56 +0900
Subject: Avoid calling switchToLastInputMethod when other IMEs are in effect
Bug: 7268389
Change-Id: I4d960cbf063002b4dc0ea813c966366b56c0346d
---
java/src/com/android/inputmethod/latin/LatinIME.java | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 311355374..494846b04 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1219,22 +1219,25 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mConnection.performEditorAction(actionId);
}
+ // TODO: Revise the language switch key behavior to make it much smarter and more reasonable.
private void handleLanguageSwitchKey() {
- final boolean includesOtherImes = mCurrentSettings.mIncludesOtherImesInLanguageSwitchList;
final IBinder token = getWindow().getWindow().getAttributes().token;
+ if (mCurrentSettings.mIncludesOtherImesInLanguageSwitchList) {
+ mImm.switchToNextInputMethod(token, false /* onlyCurrentIme */);
+ return;
+ }
if (mShouldSwitchToLastSubtype) {
final InputMethodSubtype lastSubtype = mImm.getLastInputMethodSubtype();
final boolean lastSubtypeBelongsToThisIme =
ImfUtils.checkIfSubtypeBelongsToThisImeAndEnabled(this, lastSubtype);
- if ((includesOtherImes || lastSubtypeBelongsToThisIme)
- && mImm.switchToLastInputMethod(token)) {
+ if (lastSubtypeBelongsToThisIme && mImm.switchToLastInputMethod(token)) {
mShouldSwitchToLastSubtype = false;
} else {
- mImm.switchToNextInputMethod(token, !includesOtherImes);
+ mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */);
mShouldSwitchToLastSubtype = true;
}
} else {
- mImm.switchToNextInputMethod(token, !includesOtherImes);
+ mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */);
}
}
--
cgit v1.2.3-83-g751a
From d445b56ce14152b30143302899790af255691148 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Wed, 3 Oct 2012 13:01:52 +0900
Subject: Fix possible NPE caused while monkey test
Bug: 7269036
Change-Id: I9054b33ad3c8996cac3ee5f0e9c01ba8ceea4971
---
.../android/inputmethod/keyboard/KeyboardSwitcher.java | 6 +++++-
java/src/com/android/inputmethod/latin/LatinIME.java | 8 ++++++--
.../com/android/inputmethod/latin/WordComposer.java | 18 ++++++++++--------
3 files changed, 21 insertions(+), 11 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 88d7b667f..e99e956e2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -390,7 +390,11 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
public int getManualCapsMode() {
- switch (getKeyboard().mId.mElementId) {
+ final Keyboard keyboard = getKeyboard();
+ if (keyboard == null) {
+ return WordComposer.CAPS_MODE_OFF;
+ }
+ switch (keyboard.mId.mElementId) {
case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
return WordComposer.CAPS_MODE_MANUAL_SHIFT_LOCKED;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 311355374..fe6ad4901 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1910,6 +1910,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
private SuggestedWords getSuggestedWords(final int sessionId) {
+ final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
+ if (keyboard == null) {
+ return SuggestedWords.EMPTY;
+ }
final String typedWord = mWordComposer.getTypedWord();
// Get the word on which we should search the bigrams. If we are composing a word, it's
// whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
@@ -1919,8 +1923,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mConnection.getNthPreviousWord(mCurrentSettings.mWordSeparators,
mWordComposer.isComposingWord() ? 2 : 1);
final SuggestedWords suggestedWords = mSuggest.getSuggestedWords(mWordComposer,
- prevWord, mKeyboardSwitcher.getKeyboard().getProximityInfo(),
- mCurrentSettings.mCorrectionEnabled, sessionId);
+ prevWord, keyboard.getProximityInfo(), mCurrentSettings.mCorrectionEnabled,
+ sessionId);
return maybeRetrieveOlderSuggestions(typedWord, suggestedWords);
}
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 8a1bbed12..da0071adc 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -177,14 +177,16 @@ public final class WordComposer {
* Internal method to retrieve reasonable proximity info for a character.
*/
private void addKeyInfo(final int codePoint, final Keyboard keyboard) {
- final Key key = keyboard.getKey(codePoint);
- if (key != null) {
- final int x = key.mX + key.mWidth / 2;
- final int y = key.mY + key.mHeight / 2;
- add(codePoint, x, y);
- return;
+ final int x, y;
+ final Key key;
+ if (keyboard != null && (key = keyboard.getKey(codePoint)) != null) {
+ x = key.mX + key.mWidth / 2;
+ y = key.mY + key.mHeight / 2;
+ } else {
+ x = Constants.NOT_A_COORDINATE;
+ y = Constants.NOT_A_COORDINATE;
}
- add(codePoint, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
+ add(codePoint, x, y);
}
/**
@@ -195,7 +197,7 @@ public final class WordComposer {
reset();
final int length = word.length();
for (int i = 0; i < length; i = Character.offsetByCodePoints(word, i, 1)) {
- int codePoint = Character.codePointAt(word, i);
+ final int codePoint = Character.codePointAt(word, i);
addKeyInfo(codePoint, keyboard);
}
mIsResumed = true;
--
cgit v1.2.3-83-g751a
From 4ad4ff618f5102148d73e3c04d809942bcf16f86 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Wed, 3 Oct 2012 12:34:52 +0900
Subject: Add makeCharGroupFlags.
Change-Id: Id2c580f21b77f66a97c5fbdf4542fdafe6c43614
---
.../latin/makedict/BinaryDictInputOutput.java | 89 ++++++++++++----------
.../inputmethod/latin/makedict/FormatSpec.java | 12 ++-
2 files changed, 57 insertions(+), 44 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index ba29523c8..136c0c43f 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -720,53 +720,60 @@ public final class BinaryDictInputOutput {
return 3;
}
- private static byte makeCharGroupFlags(final CharGroup group, final int groupAddress,
- final int childrenOffset, final FormatOptions formatOptions) {
+ /**
+ * Makes the flag value for a char group.
+ *
+ * @param hasMultipleChars whether the group has multiple chars.
+ * @param isTerminal whether the group is terminal.
+ * @param childrenAddressSize the size of a children address.
+ * @param hasShortcuts whether the group has shortcuts.
+ * @param hasBigrams whether the group has bigrams.
+ * @param isNotAWord whether the group is not a word.
+ * @param isBlackListEntry whether the group is a blacklist entry.
+ * @param formatOptions file format options.
+ * @return the flags
+ */
+ static int makeCharGroupFlags(final boolean hasMultipleChars, final boolean isTerminal,
+ final int childrenAddressSize, final boolean hasShortcuts, final boolean hasBigrams,
+ final boolean isNotAWord, final boolean isBlackListEntry,
+ final FormatOptions formatOptions) {
byte flags = 0;
- if (group.mChars.length > 1) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS;
- if (group.mFrequency >= 0) {
- flags |= FormatSpec.FLAG_IS_TERMINAL;
- }
- if (null != group.mChildren) {
- final int byteSize = formatOptions.mSupportsDynamicUpdate
- ? FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE : getByteSize(childrenOffset);
- switch (byteSize) {
- case 1:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE;
- break;
- case 2:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES;
- break;
- case 3:
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
- break;
- default:
- throw new RuntimeException("Node with a strange address");
- }
- } else if (formatOptions.mSupportsDynamicUpdate) {
- flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
- }
- if (null != group.mShortcutTargets) {
- if (DBG && 0 == group.mShortcutTargets.size()) {
- throw new RuntimeException("0-sized shortcut list must be null");
- }
- flags |= FormatSpec.FLAG_HAS_SHORTCUT_TARGETS;
- }
- if (null != group.mBigrams) {
- if (DBG && 0 == group.mBigrams.size()) {
- throw new RuntimeException("0-sized bigram list must be null");
+ if (hasMultipleChars) flags |= FormatSpec.FLAG_HAS_MULTIPLE_CHARS;
+ if (isTerminal) flags |= FormatSpec.FLAG_IS_TERMINAL;
+ if (formatOptions.mSupportsDynamicUpdate) {
+ flags |= FormatSpec.FLAG_IS_NOT_MOVED;
+ } else if (true) {
+ switch (childrenAddressSize) {
+ case 1:
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_ONEBYTE;
+ break;
+ case 2:
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_TWOBYTES;
+ break;
+ case 3:
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_THREEBYTES;
+ break;
+ case 0:
+ flags |= FormatSpec.FLAG_GROUP_ADDRESS_TYPE_NOADDRESS;
+ break;
+ default:
+ throw new RuntimeException("Node with a strange address");
}
- flags |= FormatSpec.FLAG_HAS_BIGRAMS;
- }
- if (group.mIsNotAWord) {
- flags |= FormatSpec.FLAG_IS_NOT_A_WORD;
- }
- if (group.mIsBlacklistEntry) {
- flags |= FormatSpec.FLAG_IS_BLACKLISTED;
}
+ if (hasShortcuts) flags |= FormatSpec.FLAG_HAS_SHORTCUT_TARGETS;
+ if (hasBigrams) flags |= FormatSpec.FLAG_HAS_BIGRAMS;
+ if (isNotAWord) flags |= FormatSpec.FLAG_IS_NOT_A_WORD;
+ if (isBlackListEntry) flags |= FormatSpec.FLAG_IS_BLACKLISTED;
return flags;
}
+ private static byte makeCharGroupFlags(final CharGroup group, final int groupAddress,
+ final int childrenOffset, final FormatOptions formatOptions) {
+ return (byte) makeCharGroupFlags(group.mChars.length > 1, group.mFrequency >= 0,
+ getByteSize(childrenOffset), group.mShortcutTargets != null, group.mBigrams != null,
+ group.mIsNotAWord, group.mIsBlacklistEntry, formatOptions);
+ }
+
/**
* Makes the flag value for a bigram.
*
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index b3fbb9fb5..5ef35a1cc 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -59,8 +59,9 @@ public final class FormatSpec {
* l | 10 = 2 bytes : FLAG_GROUP_ADDRESS_TYPE_TWOBYTES
* a | 11 = 3 bytes : FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
* g | ELSE
- * s | is moved ? 2 bits, 11 = no
- * | 01 = yes
+ * s | is moved ? 2 bits, 11 = no : FLAG_IS_NOT_MOVED
+ * | This must be the same as FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
+ * | 01 = yes : FLAG_IS_MOVED
* | the new address is stored in the same place as the parent address
* | has several chars ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_MULTIPLE_CHARS
* | has a terminal ? 1 bit, 1 = yes, 0 = no : FLAG_IS_TERMINAL
@@ -170,6 +171,7 @@ public final class FormatSpec {
static final int PARENT_ADDRESS_SIZE = 3;
static final int FORWARD_LINK_ADDRESS_SIZE = 3;
+ // These flags are used only in the static dictionary.
static final int MASK_GROUP_ADDRESS_TYPE = 0xC0;
static final int FLAG_GROUP_ADDRESS_TYPE_NOADDRESS = 0x00;
static final int FLAG_GROUP_ADDRESS_TYPE_ONEBYTE = 0x40;
@@ -183,7 +185,11 @@ public final class FormatSpec {
static final int FLAG_HAS_BIGRAMS = 0x04;
static final int FLAG_IS_NOT_A_WORD = 0x02;
static final int FLAG_IS_BLACKLISTED = 0x01;
- static final int FLAG_IS_MOVED = 0x40;
+
+ // These flags are used only in the dynamic dictionary.
+ static final int FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE = 0x40;
+ static final int FLAG_IS_MOVED = 0x00 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
+ static final int FLAG_IS_NOT_MOVED = 0x80 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
static final int FLAG_ATTRIBUTE_HAS_NEXT = 0x80;
static final int FLAG_ATTRIBUTE_OFFSET_NEGATIVE = 0x40;
--
cgit v1.2.3-83-g751a
From 3e5a3c18bebbfb56012383411b24ee81ffde09cb Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Wed, 3 Oct 2012 14:46:47 +0900
Subject: Add final modifier to the classes under suggestions sub-package
Change-Id: I19fc8eaac1aebef9cf4deb004e78484ff9a1e7ca
---
.../latin/suggestions/MoreSuggestionsView.java | 28 +++----
.../latin/suggestions/SuggestionStripView.java | 88 ++++++++++++----------
2 files changed, 62 insertions(+), 54 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index 9b9a35478..740476f62 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -56,17 +56,17 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
final KeyboardActionListener mSuggestionsPaneListener =
new KeyboardActionListener.Adapter() {
@Override
- public void onPressKey(int primaryCode) {
+ public void onPressKey(final int primaryCode) {
mListener.onPressKey(primaryCode);
}
@Override
- public void onReleaseKey(int primaryCode, boolean withSliding) {
+ public void onReleaseKey(final int primaryCode, final boolean withSliding) {
mListener.onReleaseKey(primaryCode, withSliding);
}
@Override
- public void onCodeInput(int primaryCode, int x, int y) {
+ public void onCodeInput(final int primaryCode, final int x, final int y) {
final int index = primaryCode - MoreSuggestions.SUGGESTION_CODE_BASE;
if (index >= 0 && index < SuggestionStripView.MAX_SUGGESTIONS) {
mListener.onCustomRequest(index);
@@ -79,11 +79,12 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
}
};
- public MoreSuggestionsView(Context context, AttributeSet attrs) {
+ public MoreSuggestionsView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.moreSuggestionsViewStyle);
}
- public MoreSuggestionsView(Context context, AttributeSet attrs, int defStyle) {
+ public MoreSuggestionsView(final Context context, final AttributeSet attrs,
+ final int defStyle) {
super(context, attrs, defStyle);
final Resources res = context.getResources();
@@ -94,7 +95,7 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
}
@Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final Keyboard keyboard = getKeyboard();
if (keyboard != null) {
final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
@@ -106,7 +107,7 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
}
@Override
- public void setKeyboard(Keyboard keyboard) {
+ public void setKeyboard(final Keyboard keyboard) {
super.setKeyboard(keyboard);
mModalPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop());
mSlidingPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
@@ -134,15 +135,16 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
}
@Override
- public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+ public void setKeyPreviewPopupEnabled(final boolean previewEnabled, final int delay) {
// Suggestions pane needs no pop-up key preview displayed, so we pass always false with a
// delay of 0. The delay does not matter actually since the popup is not shown anyway.
super.setKeyPreviewPopupEnabled(false, 0);
}
@Override
- public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
- PopupWindow window, KeyboardActionListener listener) {
+ public void showMoreKeysPanel(final View parentView, final Controller controller,
+ final int pointX, final int pointY, final PopupWindow window,
+ final KeyboardActionListener listener) {
mController = controller;
mListener = listener;
final View container = (View)getParent();
@@ -175,12 +177,12 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
}
@Override
- public int translateX(int x) {
+ public int translateX(final int x) {
return x - mOriginX;
}
@Override
- public int translateY(int y) {
+ public int translateY(final int y) {
return y - mOriginY;
}
@@ -207,7 +209,7 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
};
@Override
- public boolean onTouchEvent(MotionEvent me) {
+ public boolean onTouchEvent(final MotionEvent me) {
final int action = me.getAction();
final long eventTime = me.getEventTime();
final int index = me.getActionIndex();
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 94283f242..d978c371a 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -85,7 +85,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
static final boolean DBG = LatinImeLogger.sDBG;
private final ViewGroup mSuggestionsStrip;
- private KeyboardView mKeyboardView;
+ KeyboardView mKeyboardView;
private final View mMoreSuggestionsContainer;
private final MoreSuggestionsView mMoreSuggestionsView;
@@ -99,8 +99,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final PopupWindow mPreviewPopup;
private final TextView mPreviewText;
- private Listener mListener;
- private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
+ Listener mListener;
+ SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
private final SuggestionStripViewParams mParams;
private static final float MIN_TEXT_XSCALE = 0.70f;
@@ -110,12 +110,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private static final class UiHandler extends StaticInnerHandlerWrapper {
private static final int MSG_HIDE_PREVIEW = 0;
- public UiHandler(SuggestionStripView outerInstance) {
+ public UiHandler(final SuggestionStripView outerInstance) {
super(outerInstance);
}
@Override
- public void dispatchMessage(Message msg) {
+ public void dispatchMessage(final Message msg) {
final SuggestionStripView suggestionStripView = getOuterInstance();
switch (msg.what) {
case MSG_HIDE_PREVIEW:
@@ -179,8 +179,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final TextView mLeftwardsArrowView;
private final TextView mHintToSaveView;
- public SuggestionStripViewParams(Context context, AttributeSet attrs, int defStyle,
- ArrayList words, ArrayList dividers, ArrayList infos) {
+ public SuggestionStripViewParams(final Context context, final AttributeSet attrs,
+ final int defStyle, final ArrayList words, final ArrayList dividers,
+ final ArrayList infos) {
mWords = words;
mDividers = dividers;
mInfos = infos;
@@ -252,7 +253,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return mMaxMoreSuggestionsRow * mMoreSuggestionsRowHeight + mMoreSuggestionsBottomGap;
}
- public int setMoreSuggestionsHeight(int remainingHeight) {
+ public int setMoreSuggestionsHeight(final int remainingHeight) {
final int currentHeight = getMoreSuggestionsHeight();
if (currentHeight <= remainingHeight) {
return currentHeight;
@@ -264,7 +265,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return newHeight;
}
- private static Drawable getMoreSuggestionsHint(Resources res, float textSize, int color) {
+ private static Drawable getMoreSuggestionsHint(final Resources res, final float textSize,
+ final int color) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setTextAlign(Align.CENTER);
@@ -281,7 +283,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return new BitmapDrawable(res, buffer);
}
- private CharSequence getStyledSuggestionWord(SuggestedWords suggestedWords, int pos) {
+ private CharSequence getStyledSuggestionWord(final SuggestedWords suggestedWords,
+ final int pos) {
final CharSequence word = suggestedWords.getWord(pos);
final boolean isAutoCorrect = pos == 1 && suggestedWords.willAutoCorrect();
final boolean isTypedWordValid = pos == 0 && suggestedWords.mTypedWordValid;
@@ -301,7 +304,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return spannedWord;
}
- private int getWordPosition(int index, SuggestedWords suggestedWords) {
+ private int getWordPosition(final int index, final SuggestedWords suggestedWords) {
// TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more
// suggestions.
final int centerPos = suggestedWords.willAutoCorrect() ? 1 : 0;
@@ -314,7 +317,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
}
- private int getSuggestionTextColor(int index, SuggestedWords suggestedWords, int pos) {
+ private int getSuggestionTextColor(final int index, final SuggestedWords suggestedWords,
+ final int pos) {
// TODO: Need to revisit this logic with bigram suggestions
final boolean isSuggested = (pos != 0);
@@ -357,8 +361,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
params.gravity = Gravity.CENTER;
}
- public void layout(SuggestedWords suggestedWords, ViewGroup stripView, ViewGroup placer,
- int stripWidth) {
+ public void layout(final SuggestedWords suggestedWords, final ViewGroup stripView,
+ final ViewGroup placer, final int stripWidth) {
if (suggestedWords.mIsPunctuationSuggestions) {
layoutPunctuationSuggestions(suggestedWords, stripView);
return;
@@ -420,14 +424,14 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
}
- private int getSuggestionWidth(int index, int maxWidth) {
+ private int getSuggestionWidth(final int index, final int maxWidth) {
final int paddings = mPadding * mSuggestionsCountInStrip;
final int dividers = mDividerWidth * (mSuggestionsCountInStrip - 1);
final int availableWidth = maxWidth - paddings - dividers;
return (int)(availableWidth * getSuggestionWeight(index));
}
- private float getSuggestionWeight(int index) {
+ private float getSuggestionWeight(final int index) {
if (index == mCenterSuggestionIndex) {
return mCenterSuggestionWeight;
} else {
@@ -436,7 +440,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
}
- private void setupTexts(SuggestedWords suggestedWords, int countInStrip) {
+ private void setupTexts(final SuggestedWords suggestedWords, final int countInStrip) {
mTexts.clear();
final int count = Math.min(suggestedWords.size(), countInStrip);
for (int pos = 0; pos < count; pos++) {
@@ -449,8 +453,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
}
- private void layoutPunctuationSuggestions(SuggestedWords suggestedWords,
- ViewGroup stripView) {
+ private void layoutPunctuationSuggestions(final SuggestedWords suggestedWords,
+ final ViewGroup stripView) {
final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP);
for (int index = 0; index < countInStrip; index++) {
if (index != 0) {
@@ -471,8 +475,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mMoreSuggestionsAvailable = false;
}
- public void layoutAddToDictionaryHint(CharSequence word, ViewGroup stripView,
- int stripWidth, CharSequence hintText, OnClickListener listener) {
+ public void layoutAddToDictionaryHint(final CharSequence word, final ViewGroup stripView,
+ final int stripWidth, final CharSequence hintText, final OnClickListener listener) {
final int width = stripWidth - mDividerWidth - mPadding * 2;
final TextView wordView = mWordToSaveView;
@@ -513,11 +517,11 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return (CharSequence)mWordToSaveView.getTag();
}
- public boolean isAddToDictionaryShowing(View v) {
+ public boolean isAddToDictionaryShowing(final View v) {
return v == mWordToSaveView || v == mHintToSaveView || v == mLeftwardsArrowView;
}
- private static void setLayoutWeight(View v, float weight, int height) {
+ private static void setLayoutWeight(final View v, final float weight, final int height) {
final ViewGroup.LayoutParams lp = v.getLayoutParams();
if (lp instanceof LinearLayout.LayoutParams) {
final LinearLayout.LayoutParams llp = (LinearLayout.LayoutParams)lp;
@@ -527,7 +531,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
}
- private static float getTextScaleX(CharSequence text, int maxWidth, TextPaint paint) {
+ private static float getTextScaleX(final CharSequence text, final int maxWidth,
+ final TextPaint paint) {
paint.setTextScaleX(1.0f);
final int width = getTextWidth(text, paint);
if (width <= maxWidth) {
@@ -536,8 +541,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return maxWidth / (float)width;
}
- private static CharSequence getEllipsizedText(CharSequence text, int maxWidth,
- TextPaint paint) {
+ private static CharSequence getEllipsizedText(final CharSequence text, final int maxWidth,
+ final TextPaint paint) {
if (text == null) return null;
paint.setTextScaleX(1.0f);
final int width = getTextWidth(text, paint);
@@ -558,7 +563,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return ellipsized;
}
- private static int getTextWidth(CharSequence text, TextPaint paint) {
+ private static int getTextWidth(final CharSequence text, final TextPaint paint) {
if (TextUtils.isEmpty(text)) return 0;
final Typeface savedTypeface = paint.getTypeface();
paint.setTypeface(getTextTypeface(text));
@@ -573,7 +578,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
return width;
}
- private static Typeface getTextTypeface(CharSequence text) {
+ private static Typeface getTextTypeface(final CharSequence text) {
if (!(text instanceof SpannableString))
return Typeface.DEFAULT;
@@ -595,11 +600,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
* @param context
* @param attrs
*/
- public SuggestionStripView(Context context, AttributeSet attrs) {
+ public SuggestionStripView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.suggestionStripViewStyle);
}
- public SuggestionStripView(Context context, AttributeSet attrs, int defStyle) {
+ public SuggestionStripView(final Context context, final AttributeSet attrs,
+ final int defStyle) {
super(context, attrs, defStyle);
final LayoutInflater inflater = LayoutInflater.from(context);
@@ -660,12 +666,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
* A connection back to the input method.
* @param listener
*/
- public void setListener(Listener listener, View inputView) {
+ public void setListener(final Listener listener, final View inputView) {
mListener = listener;
mKeyboardView = (KeyboardView)inputView.findViewById(R.id.keyboard_view);
}
- public void setSuggestions(SuggestedWords suggestedWords) {
+ public void setSuggestions(final SuggestedWords suggestedWords) {
if (suggestedWords == null)
return;
@@ -677,7 +683,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
}
- public int setMoreSuggestionsHeight(int remainingHeight) {
+ public int setMoreSuggestionsHeight(final int remainingHeight) {
return mParams.setMoreSuggestionsHeight(remainingHeight);
}
@@ -686,7 +692,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
&& mParams.isAddToDictionaryShowing(mSuggestionsStrip.getChildAt(0));
}
- public void showAddToDictionaryHint(CharSequence word, CharSequence hintText) {
+ public void showAddToDictionaryHint(final CharSequence word, final CharSequence hintText) {
clear();
mParams.layoutAddToDictionaryHint(word, mSuggestionsStrip, getWidth(), hintText, this);
}
@@ -710,14 +716,14 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
dismissMoreSuggestions();
}
- private void hidePreview() {
+ void hidePreview() {
mPreviewPopup.dismiss();
}
private final KeyboardActionListener mMoreSuggestionsListener =
new KeyboardActionListener.Adapter() {
@Override
- public boolean onCustomRequest(int requestCode) {
+ public boolean onCustomRequest(final int requestCode) {
final int index = requestCode;
final CharSequence word = mSuggestedWords.getWord(index);
mListener.pickSuggestionManually(index, word);
@@ -739,7 +745,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
};
- private boolean dismissMoreSuggestions() {
+ boolean dismissMoreSuggestions() {
if (mMoreSuggestionsWindow.isShowing()) {
mMoreSuggestionsWindow.dismiss();
return true;
@@ -748,11 +754,11 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
@Override
- public boolean onLongClick(View view) {
+ public boolean onLongClick(final View view) {
return showMoreSuggestions();
}
- private boolean showMoreSuggestions() {
+ boolean showMoreSuggestions() {
final Keyboard parentKeyboard = KeyboardSwitcher.getInstance().getKeyboard();
if (parentKeyboard == null) {
return false;
@@ -810,7 +816,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
};
@Override
- public boolean dispatchTouchEvent(MotionEvent me) {
+ public boolean dispatchTouchEvent(final MotionEvent me) {
if (!mMoreSuggestionsWindow.isShowing()
|| mMoreSuggestionsMode == MORE_SUGGESTIONS_IN_MODAL_MODE) {
mLastX = (int)me.getX();
@@ -852,7 +858,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
@Override
- public void onClick(View view) {
+ public void onClick(final View view) {
if (mParams.isAddToDictionaryShowing(view)) {
mListener.addWordToUserDictionary(mParams.getAddToDictionaryWord().toString());
clear();
--
cgit v1.2.3-83-g751a
From c6ff7c42d9aeafe2b2d21a34be10f1e9a450153a Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Wed, 3 Oct 2012 14:06:44 +0900
Subject: Add SuggestedWords.isEmpty() method
Change-Id: I0fcb104a6a81aee4b99f5ee848eba7495630dc7d
---
.../inputmethod/compat/SuggestionSpanUtils.java | 4 ++--
java/src/com/android/inputmethod/latin/LatinIME.java | 20 ++++++++------------
.../android/inputmethod/latin/SuggestedWords.java | 4 ++++
.../latin/suggestions/SuggestionStripView.java | 3 ---
4 files changed, 14 insertions(+), 17 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index 159f43650..9a89eedd0 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -108,8 +108,8 @@ public final class SuggestionSpanUtils {
CharSequence pickedWord, SuggestedWords suggestedWords, boolean dictionaryAvailable) {
if (!dictionaryAvailable || TextUtils.isEmpty(pickedWord)
|| CONSTRUCTOR_SuggestionSpan == null
- || suggestedWords == null || suggestedWords.size() == 0
- || suggestedWords.mIsPrediction || suggestedWords.mIsPunctuationSuggestions
+ || suggestedWords.isEmpty() || suggestedWords.mIsPrediction
+ || suggestedWords.mIsPunctuationSuggestions
|| OBJ_SUGGESTIONS_MAX_SIZE == null) {
return pickedWord;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 69a4fa63c..c0938cf97 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1518,8 +1518,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
final boolean dismissGestureFloatingPreviewText) {
- final String batchInputText = (suggestedWords.size() > 0)
- ? suggestedWords.getWord(0) : null;
+ final String batchInputText = suggestedWords.isEmpty()
+ ? null : suggestedWords.getWord(0);
final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
mainKeyboardView.showGestureFloatingPreviewText(batchInputText);
showSuggestionStrip(suggestedWords, null);
@@ -1537,8 +1537,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
public void onEndBatchInput(final InputPointers batchPointers) {
final SuggestedWords suggestedWords = BatchInputUpdater.getInstance().onEndBatchInput(
batchPointers, this);
- final String batchInputText = (suggestedWords.size() > 0)
- ? suggestedWords.getWord(0) : null;
+ final String batchInputText = suggestedWords.isEmpty()
+ ? null : suggestedWords.getWord(0);
if (TextUtils.isEmpty(batchInputText)) {
return;
}
@@ -1963,19 +1963,15 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private void showSuggestionStrip(final SuggestedWords suggestedWords,
final CharSequence typedWord) {
- if (null == suggestedWords || suggestedWords.size() <= 0) {
+ if (suggestedWords.isEmpty()) {
clearSuggestionStrip();
return;
}
final CharSequence autoCorrection;
- if (suggestedWords.size() > 0) {
- if (suggestedWords.mWillAutoCorrect) {
- autoCorrection = suggestedWords.getWord(1);
- } else {
- autoCorrection = typedWord;
- }
+ if (suggestedWords.mWillAutoCorrect) {
+ autoCorrection = suggestedWords.getWord(1);
} else {
- autoCorrection = null;
+ autoCorrection = typedWord;
}
mWordComposer.setAutoCorrection(autoCorrection);
final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 52e292a86..ad94affb2 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -53,6 +53,10 @@ public final class SuggestedWords {
mIsPrediction = isPrediction;
}
+ public boolean isEmpty() {
+ return mSuggestedWordInfoList.isEmpty();
+ }
+
public int size() {
return mSuggestedWordInfoList.size();
}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index d978c371a..6056af95c 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -672,9 +672,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
public void setSuggestions(final SuggestedWords suggestedWords) {
- if (suggestedWords == null)
- return;
-
clear();
mSuggestedWords = suggestedWords;
mParams.layout(mSuggestedWords, mSuggestionsStrip, this, getWidth());
--
cgit v1.2.3-83-g751a
From 66d955ad711d4a1248157056a1d3d643af19fd3f Mon Sep 17 00:00:00 2001
From: Satoshi Kataoka
Date: Wed, 3 Oct 2012 17:15:47 +0900
Subject: Throw illegal argument exception in BinaryDictionary::editDistance
Bug: 7276803
Change-Id: Icd9bdec0a04179a29d00336819d205627f77b71a
---
java/src/com/android/inputmethod/latin/BinaryDictionary.java | 3 +++
1 file changed, 3 insertions(+)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index e084cb306..7184f1d8a 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -187,6 +187,9 @@ public final class BinaryDictionary extends Dictionary {
}
public static int editDistance(String before, String after) {
+ if (before == null || after == null) {
+ throw new IllegalArgumentException();
+ }
return editDistanceNative(before.toCharArray(), after.toCharArray());
}
--
cgit v1.2.3-83-g751a
From 7223cc2ef1d7fd4ad4ab62166114b36ce7313c55 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Wed, 3 Oct 2012 14:59:27 +0900
Subject: Add MAX_BIGRAMS_IN_A_GROUP.
Change-Id: I128d5deb8e523045d7ad77d7a8fd3db944f71238
---
.../android/inputmethod/latin/makedict/BinaryDictInputOutput.java | 6 +++++-
java/src/com/android/inputmethod/latin/makedict/FormatSpec.java | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 136c0c43f..14fc36681 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -1297,7 +1297,8 @@ public final class BinaryDictInputOutput {
ArrayList bigrams = null;
if (0 != (flags & FormatSpec.FLAG_HAS_BIGRAMS)) {
bigrams = new ArrayList();
- while (true) {
+ int bigramCount = 0;
+ while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
final int bigramFlags = buffer.readUnsignedByte();
++addressPointer;
final int sign = 0 == (bigramFlags & FormatSpec.FLAG_ATTRIBUTE_OFFSET_NEGATIVE)
@@ -1325,6 +1326,9 @@ public final class BinaryDictInputOutput {
bigramAddress));
if (0 == (bigramFlags & FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT)) break;
}
+ if (bigramCount >= FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
+ MakedictLog.d("too many bigrams in a group.");
+ }
}
return new CharGroupInfo(originalGroupAddress, addressPointer, flags, characters, frequency,
parentAddress, childrenAddress, shortcutTargets, bigrams);
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 5ef35a1cc..3fd9e4037 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -216,6 +216,7 @@ public final class FormatSpec {
static final int MAX_CHARGROUPS_FOR_ONE_BYTE_CHARGROUP_COUNT = 0x7F; // 127
static final int MAX_CHARGROUPS_IN_A_NODE = 0x7FFF; // 32767
+ static final int MAX_BIGRAMS_IN_A_GROUP = 10000;
static final int MAX_TERMINAL_FREQUENCY = 255;
static final int MAX_BIGRAM_FREQUENCY = 15;
--
cgit v1.2.3-83-g751a
From a853356b82e2dc74962243e3143c0ff7a33f3c20 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Wed, 3 Oct 2012 17:23:39 +0900
Subject: Add isDeletedGroup.
Change-Id: I83f09c068868e5e6e1b46f494a6ef957f0b466d8
---
.../latin/makedict/BinaryDictIOUtils.java | 29 ++++++++++++++--------
.../latin/makedict/BinaryDictInputOutput.java | 8 ++++++
.../inputmethod/latin/makedict/FormatSpec.java | 2 ++
3 files changed, 29 insertions(+), 10 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 5ed910c50..7faad78c4 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -95,7 +95,9 @@ public final class BinaryDictIOUtils {
final boolean isMovedGroup = BinaryDictInputOutput.isMovedGroup(info.mFlags,
formatOptions);
- if (!isMovedGroup
+ final boolean isDeletedGroup = BinaryDictInputOutput.isDeletedGroup(info.mFlags,
+ formatOptions);
+ if (!isMovedGroup && !isDeletedGroup
&& info.mFrequency != FusionDictionary.CharGroup.NOT_A_TERMINAL) {// found word
words.put(info.mOriginalAddress, new String(pushedChars, 0, index));
frequencies.put(info.mOriginalAddress, info.mFrequency);
@@ -179,10 +181,13 @@ public final class BinaryDictIOUtils {
final int charGroupPos = buffer.position();
final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
buffer.position(), header.mFormatOptions);
- if (BinaryDictInputOutput.isMovedGroup(currentInfo.mFlags,
- header.mFormatOptions)) {
- continue;
- }
+ final boolean isMovedGroup =
+ BinaryDictInputOutput.isMovedGroup(currentInfo.mFlags,
+ header.mFormatOptions);
+ final boolean isDeletedGroup =
+ BinaryDictInputOutput.isDeletedGroup(currentInfo.mFlags,
+ header.mFormatOptions);
+ if (isMovedGroup) continue;
boolean same = true;
for (int p = 0, j = word.offsetByCodePoints(0, wordPos);
p < currentInfo.mCharacters.length;
@@ -197,7 +202,8 @@ public final class BinaryDictIOUtils {
if (same) {
// found the group matches the word.
if (wordPos + currentInfo.mCharacters.length == wordLen) {
- if (currentInfo.mFrequency == CharGroup.NOT_A_TERMINAL) {
+ if (currentInfo.mFrequency == CharGroup.NOT_A_TERMINAL
+ || isDeletedGroup) {
return FormatSpec.NOT_VALID_WORD;
} else {
return charGroupPos;
@@ -233,6 +239,10 @@ public final class BinaryDictIOUtils {
return FormatSpec.NOT_VALID_WORD;
}
+ private static int markAsDeleted(final int flags) {
+ return (flags & (~FormatSpec.MASK_GROUP_ADDRESS_TYPE)) | FormatSpec.FLAG_IS_DELETED;
+ }
+
/**
* Delete the word from the binary file.
*
@@ -250,9 +260,8 @@ public final class BinaryDictIOUtils {
buffer.position(wordPosition);
final int flags = buffer.readUnsignedByte();
- final int newFlags = flags ^ FormatSpec.FLAG_IS_TERMINAL;
buffer.position(wordPosition);
- buffer.put((byte)newFlags);
+ buffer.put((byte)markAsDeleted(flags));
}
/**
@@ -302,7 +311,7 @@ public final class BinaryDictIOUtils {
}
/**
- * Update a parent address in a CharGroup that is addressed by groupOriginAddress.
+ * Update a parent address in a CharGroup that is referred to by groupOriginAddress.
*
* @param buffer the buffer to write.
* @param groupOriginAddress the address of the group.
@@ -380,7 +389,7 @@ public final class BinaryDictIOUtils {
final int flags = buffer.readUnsignedByte();
final int parentAddress = BinaryDictInputOutput.readParentAddress(buffer, formatOptions);
skipString(buffer, (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
- if ((FormatSpec.FLAG_IS_TERMINAL) != 0) buffer.readUnsignedByte();
+ if ((flags & FormatSpec.FLAG_IS_TERMINAL) != 0) buffer.readUnsignedByte();
final int childrenOffset = newChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS
? FormatSpec.NO_CHILDREN_ADDRESS : newChildrenAddress - buffer.position();
writeSInt24ToBuffer(buffer, childrenOffset);
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 14fc36681..b9fd15fa0 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -401,6 +401,14 @@ public final class BinaryDictInputOutput {
return options.mSupportsDynamicUpdate && ((flags & FormatSpec.FLAG_IS_MOVED) == 1);
}
+ /**
+ * Helper method to check whether the group is deleted.
+ */
+ public static boolean isDeletedGroup(final int flags, final FormatOptions formatOptions) {
+ return formatOptions.mSupportsDynamicUpdate
+ && ((flags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) == FormatSpec.FLAG_IS_DELETED);
+ }
+
/**
* Helper method to check whether the dictionary can be updated dynamically.
*/
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 3fd9e4037..ca851c6a9 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -63,6 +63,7 @@ public final class FormatSpec {
* | This must be the same as FLAG_GROUP_ADDRESS_TYPE_THREEBYTES
* | 01 = yes : FLAG_IS_MOVED
* | the new address is stored in the same place as the parent address
+ * | is deleted? 10 = yes : FLAG_IS_DELETED
* | has several chars ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_MULTIPLE_CHARS
* | has a terminal ? 1 bit, 1 = yes, 0 = no : FLAG_IS_TERMINAL
* | has shortcut targets ? 1 bit, 1 = yes, 0 = no : FLAG_HAS_SHORTCUT_TARGETS
@@ -190,6 +191,7 @@ public final class FormatSpec {
static final int FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE = 0x40;
static final int FLAG_IS_MOVED = 0x00 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
static final int FLAG_IS_NOT_MOVED = 0x80 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
+ static final int FLAG_IS_DELETED = 0x80;
static final int FLAG_ATTRIBUTE_HAS_NEXT = 0x80;
static final int FLAG_ATTRIBUTE_OFFSET_NEGATIVE = 0x40;
--
cgit v1.2.3-83-g751a
From 38712ff27d8dccd9127cf85c94ee2c6fd91832b5 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Wed, 3 Oct 2012 17:37:52 +0900
Subject: Add updateParentAddresses.
Change-Id: Iac210131b7c003ef363e1138bf22f777a37c6a89
---
.../latin/makedict/BinaryDictIOUtils.java | 76 ++++++++++++++++++++--
.../latin/makedict/BinaryDictInputOutput.java | 2 +-
2 files changed, 72 insertions(+), 6 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 7faad78c4..6210c923e 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -28,7 +28,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Stack;
@@ -172,10 +171,7 @@ public final class BinaryDictIOUtils {
if (wordPos >= wordLen) return FormatSpec.NOT_VALID_WORD;
do {
- int groupOffset = buffer.position() - header.mHeaderSize;
final int charGroupCount = BinaryDictInputOutput.readCharGroupCount(buffer);
- groupOffset += BinaryDictInputOutput.getGroupCountSize(charGroupCount);
-
boolean foundNextCharGroup = false;
for (int i = 0; i < charGroupCount; ++i) {
final int charGroupPos = buffer.position();
@@ -217,7 +213,6 @@ public final class BinaryDictIOUtils {
buffer.position(currentInfo.mChildrenAddress);
break;
}
- groupOffset = currentInfo.mEndAddress;
}
// If we found the next char group, it is under the file pointer.
@@ -327,11 +322,82 @@ public final class BinaryDictIOUtils {
throw new RuntimeException("this file format does not support parent addresses");
}
final int flags = buffer.readUnsignedByte();
+ if (BinaryDictInputOutput.isMovedGroup(flags, formatOptions)) {
+ // if the group is moved, the parent address is stored in the destination group.
+ // We are guaranteed to process the destination group later, so there is no need to
+ // update anything here.
+ buffer.position(originalPosition);
+ return;
+ }
+ if (DBG) {
+ MakedictLog.d("update parent address flags=" + flags + ", " + groupOriginAddress);
+ }
final int parentOffset = newParentAddress - groupOriginAddress;
writeSInt24ToBuffer(buffer, parentOffset);
buffer.position(originalPosition);
}
+ private static void skipCharGroup(final FusionDictionaryBufferInterface buffer,
+ final FormatOptions formatOptions) {
+ final int flags = buffer.readUnsignedByte();
+ BinaryDictInputOutput.readParentAddress(buffer, formatOptions);
+ skipString(buffer, (flags & FormatSpec.FLAG_HAS_MULTIPLE_CHARS) != 0);
+ BinaryDictInputOutput.readChildrenAddress(buffer, flags, formatOptions);
+ if ((flags & FormatSpec.FLAG_IS_TERMINAL) != 0) buffer.readUnsignedByte();
+ if ((flags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS) != 0) {
+ final int shortcutsSize = buffer.readUnsignedShort();
+ buffer.position(buffer.position() + shortcutsSize
+ - FormatSpec.GROUP_SHORTCUT_LIST_SIZE_SIZE);
+ }
+ if ((flags & FormatSpec.FLAG_HAS_BIGRAMS) != 0) {
+ int bigramCount = 0;
+ while (bigramCount++ < FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
+ final int bigramFlags = buffer.readUnsignedByte();
+ switch (bigramFlags & FormatSpec.MASK_ATTRIBUTE_ADDRESS_TYPE) {
+ case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_ONEBYTE:
+ buffer.readUnsignedByte();
+ break;
+ case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_TWOBYTES:
+ buffer.readUnsignedShort();
+ break;
+ case FormatSpec.FLAG_ATTRIBUTE_ADDRESS_TYPE_THREEBYTES:
+ buffer.readUnsignedInt24();
+ break;
+ }
+ if ((bigramFlags & FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT) == 0) break;
+ }
+ if (bigramCount >= FormatSpec.MAX_BIGRAMS_IN_A_GROUP) {
+ throw new RuntimeException("Too many bigrams in a group.");
+ }
+ }
+ }
+
+ /**
+ * Update parent addresses in a Node that is referred to by nodeOriginAddress.
+ *
+ * @param buffer the buffer to be modified.
+ * @param nodeOriginAddress the address of a modified Node.
+ * @param newParentAddress the address to be written
+ * @param formatOptions file format options
+ */
+ public static void updateParentAddresses(final FusionDictionaryBufferInterface buffer,
+ final int nodeOriginAddress, final int newParentAddress,
+ final FormatOptions formatOptions) {
+ final int originalPosition = buffer.position();
+ buffer.position(nodeOriginAddress);
+ do {
+ final int count = BinaryDictInputOutput.readCharGroupCount(buffer);
+ for (int i = 0; i < count; ++i) {
+ updateParentAddress(buffer, buffer.position(), newParentAddress, formatOptions);
+ skipCharGroup(buffer, formatOptions);
+ }
+ final int forwardLinkAddress = buffer.readUnsignedInt24();
+ buffer.position(forwardLinkAddress);
+ } while (formatOptions.mSupportsDynamicUpdate
+ && buffer.position() != FormatSpec.NO_FORWARD_LINK_ADDRESS);
+ buffer.position(originalPosition);
+ }
+
private static void skipString(final FusionDictionaryBufferInterface buffer,
final boolean hasMultipleChars) {
if (hasMultipleChars) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index b9fd15fa0..78171d03c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -1209,7 +1209,7 @@ public final class BinaryDictInputOutput {
}
}
- private static int readChildrenAddress(final FusionDictionaryBufferInterface buffer,
+ static int readChildrenAddress(final FusionDictionaryBufferInterface buffer,
final int optionFlags, final FormatOptions options) {
if (options.mSupportsDynamicUpdate) {
final int address = buffer.readUnsignedInt24();
--
cgit v1.2.3-83-g751a
From c3a98ca306d5d6a3dfce3585b73f7431dbf90bfc Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Wed, 3 Oct 2012 17:58:22 +0900
Subject: Add writeNode.
Change-Id: I088bb6ea43ce0841d725e48b677d429e1155569d
---
.../latin/makedict/BinaryDictIOUtils.java | 111 ++++++++++++++++++++-
.../latin/makedict/BinaryDictInputOutput.java | 21 +++-
.../inputmethod/latin/makedict/FormatSpec.java | 1 +
3 files changed, 124 insertions(+), 9 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 6210c923e..096ca0992 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -33,6 +33,11 @@ import java.util.Stack;
public final class BinaryDictIOUtils {
private static final boolean DBG = false;
+ private static final int MAX_JUMPS = 10000;
+
+ private BinaryDictIOUtils() {
+ // This utility class is not publicly instantiable.
+ }
private static final class Position {
public static final int NOT_READ_GROUPCOUNT = -1;
@@ -377,8 +382,8 @@ public final class BinaryDictIOUtils {
*
* @param buffer the buffer to be modified.
* @param nodeOriginAddress the address of a modified Node.
- * @param newParentAddress the address to be written
- * @param formatOptions file format options
+ * @param newParentAddress the address to be written.
+ * @param formatOptions file format options.
*/
public static void updateParentAddresses(final FusionDictionaryBufferInterface buffer,
final int nodeOriginAddress, final int newParentAddress,
@@ -435,7 +440,7 @@ public final class BinaryDictIOUtils {
}
}
destination.write((byte)FormatSpec.GROUP_CHARACTERS_TERMINATOR);
- size++;
+ size += FormatSpec.GROUP_TERMINATOR_SIZE;
return size;
}
@@ -473,7 +478,7 @@ public final class BinaryDictIOUtils {
*/
public static int writeCharGroup(final OutputStream destination, final CharGroupInfo info)
throws IOException {
- int size = 1;
+ int size = FormatSpec.GROUP_FLAGS_SIZE;
destination.write((byte)info.mFlags);
final int parentOffset = info.mParentAddress == FormatSpec.NO_PARENT_ADDRESS ?
FormatSpec.NO_PARENT_ADDRESS : info.mParentAddress - info.mOriginalAddress;
@@ -497,9 +502,15 @@ public final class BinaryDictIOUtils {
size++;
}
+ if (DBG) {
+ MakedictLog.d("writeCharGroup origin=" + info.mOriginalAddress + ", size=" + size
+ + ", child=" + info.mChildrenAddress + ", characters ="
+ + new String(info.mCharacters, 0, info.mCharacters.length));
+ }
final int childrenOffset = info.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS ?
- 0 : info.mChildrenAddress - info.mOriginalAddress;
+ 0 : info.mChildrenAddress - (info.mOriginalAddress + size);
writeSInt24ToStream(destination, childrenOffset);
+ size += FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
if (info.mShortcutTargets != null && info.mShortcutTargets.size() > 0) {
final int shortcutListSize =
@@ -545,4 +556,94 @@ public final class BinaryDictIOUtils {
}
return size;
}
+
+ private static void updateForwardLink(final FusionDictionaryBufferInterface buffer,
+ final int nodeOriginAddress, final int newNodeAddress,
+ final FormatOptions formatOptions) {
+ buffer.position(nodeOriginAddress);
+ int jumpCount = 0;
+ while (jumpCount++ < MAX_JUMPS) {
+ final int count = BinaryDictInputOutput.readCharGroupCount(buffer);
+ for (int i = 0; i < count; ++i) skipCharGroup(buffer, formatOptions);
+ final int forwardLinkAddress = buffer.readUnsignedInt24();
+ if (forwardLinkAddress == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ buffer.position(buffer.position() - FormatSpec.FORWARD_LINK_ADDRESS_SIZE);
+ writeSInt24ToBuffer(buffer, newNodeAddress);
+ return;
+ }
+ buffer.position(forwardLinkAddress);
+ }
+ if (DBG && jumpCount >= MAX_JUMPS) {
+ throw new RuntimeException("too many jumps, probably a bug.");
+ }
+ }
+
+ /**
+ * Helper method to move a char group to the tail of the file.
+ */
+ private static int moveCharGroup(final OutputStream destination,
+ final FusionDictionaryBufferInterface buffer, final CharGroupInfo info,
+ final int nodeOriginAddress, final int oldGroupAddress,
+ final FormatOptions formatOptions) throws IOException {
+ updateParentAddress(buffer, oldGroupAddress, buffer.limit() + 1, formatOptions);
+ buffer.position(oldGroupAddress);
+ final int currentFlags = buffer.readUnsignedByte();
+ buffer.position(oldGroupAddress);
+ buffer.put((byte)(FormatSpec.FLAG_IS_MOVED | (currentFlags
+ & (~FormatSpec.MASK_MOVE_AND_DELETE_FLAG))));
+ int size = FormatSpec.GROUP_FLAGS_SIZE;
+ updateForwardLink(buffer, nodeOriginAddress, buffer.limit(), formatOptions);
+ size += writeNode(destination, new CharGroupInfo[] { info });
+ return size;
+ }
+
+ /**
+ * Compute the size of the char group.
+ */
+ private static int computeGroupSize(final CharGroupInfo info,
+ final FormatOptions formatOptions) {
+ int size = FormatSpec.GROUP_FLAGS_SIZE + FormatSpec.PARENT_ADDRESS_SIZE
+ + BinaryDictInputOutput.getGroupCharactersSize(info.mCharacters)
+ + BinaryDictInputOutput.getChildrenAddressSize(info.mFlags, formatOptions);
+ if ((info.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0) {
+ size += FormatSpec.GROUP_FREQUENCY_SIZE;
+ }
+ if (info.mShortcutTargets != null && !info.mShortcutTargets.isEmpty()) {
+ size += BinaryDictInputOutput.getShortcutListSize(info.mShortcutTargets);
+ }
+ if (info.mBigrams != null) {
+ for (final PendingAttribute attr : info.mBigrams) {
+ size += FormatSpec.GROUP_FLAGS_SIZE;
+ size += BinaryDictInputOutput.getByteSize(attr.mAddress);
+ }
+ }
+ return size;
+ }
+
+ /**
+ * Write a node to the stream.
+ *
+ * @param destination the stream to write.
+ * @param infos groups to be written.
+ * @return the size written, in bytes.
+ * @throws IOException
+ */
+ private static int writeNode(final OutputStream destination, final CharGroupInfo[] infos)
+ throws IOException {
+ int size = BinaryDictInputOutput.getGroupCountSize(infos.length);
+ switch (BinaryDictInputOutput.getGroupCountSize(infos.length)) {
+ case 1:
+ destination.write((byte)infos.length);
+ break;
+ case 2:
+ destination.write((byte)(infos.length >> 8));
+ destination.write((byte)(infos.length & 0xFF));
+ break;
+ default:
+ throw new RuntimeException("Invalid group count size.");
+ }
+ for (final CharGroupInfo info : infos) size += writeCharGroup(destination, info);
+ writeSInt24ToStream(destination, FormatSpec.NO_FORWARD_LINK_ADDRESS);
+ return size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 78171d03c..624e72f0c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -275,6 +275,21 @@ public final class BinaryDictInputOutput {
}
}
+ /**
+ * Compute the binary size of the character array.
+ *
+ * If only one character, this is the size of this character. If many, it's the sum of their
+ * sizes + 1 byte for the terminator.
+ *
+ * @param characters the character array
+ * @return the size of the char array, including the terminator if any
+ */
+ static int getGroupCharactersSize(final int[] characters) {
+ int size = CharEncoding.getCharArraySize(characters);
+ if (characters.length > 1) size += FormatSpec.GROUP_TERMINATOR_SIZE;
+ return size;
+ }
+
/**
* Compute the binary size of the character array in a group
*
@@ -285,9 +300,7 @@ public final class BinaryDictInputOutput {
* @return the size of the char array, including the terminator if any
*/
private static int getGroupCharactersSize(final CharGroup group) {
- int size = CharEncoding.getCharArraySize(group.mChars);
- if (group.hasSeveralChars()) size += FormatSpec.GROUP_TERMINATOR_SIZE;
- return size;
+ return getGroupCharactersSize(group.mChars);
}
/**
@@ -1193,7 +1206,7 @@ public final class BinaryDictInputOutput {
// Input methods: Read a binary dictionary to memory.
// readDictionaryBinary is the public entry point for them.
- private static int getChildrenAddressSize(final int optionFlags,
+ static int getChildrenAddressSize(final int optionFlags,
final FormatOptions formatOptions) {
if (formatOptions.mSupportsDynamicUpdate) return FormatSpec.SIGNED_CHILDREN_ADDRESS_SIZE;
switch (optionFlags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index ca851c6a9..e88a4aebf 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -188,6 +188,7 @@ public final class FormatSpec {
static final int FLAG_IS_BLACKLISTED = 0x01;
// These flags are used only in the dynamic dictionary.
+ static final int MASK_MOVE_AND_DELETE_FLAG = 0xC0;
static final int FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE = 0x40;
static final int FLAG_IS_MOVED = 0x00 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
static final int FLAG_IS_NOT_MOVED = 0x80 | FIXED_BIT_OF_DYNAMIC_UPDATE_MOVE;
--
cgit v1.2.3-83-g751a
From c15726482eee1fe9eb5c84e337ae5d40735da2d3 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Thu, 4 Oct 2012 15:49:08 +0900
Subject: Unlink an old file before moving the new file over it
This is unlikely to be relevant to this bug, but just in case.
Bug: 7274972
Change-Id: I56b31b377af16cc2c15ceb90a19792bed3aab367
---
java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java | 1 +
1 file changed, 1 insertion(+)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 0b115945b..46b363c10 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -200,6 +200,7 @@ public final class BinaryDictionaryFileDumper {
outputStream.flush();
outputStream.close();
final File finalFile = new File(finalFileName);
+ finalFile.delete();
if (!outputFile.renameTo(finalFile)) {
throw new IOException("Can't move the file to its final name");
}
--
cgit v1.2.3-83-g751a
From 3c6d9fe14840fd2c455ec65b6481ed78f99a5460 Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Mon, 1 Oct 2012 14:50:58 +0900
Subject: Add insertWord.
bug: 6669677
Change-Id: Ide55a4931071de9cd42c1cddae63ddd531d2feba
---
.../latin/makedict/BinaryDictIOUtils.java | 301 ++++++++++++++++++
.../latin/makedict/BinaryDictInputOutput.java | 3 +-
.../latin/makedict/FusionDictionary.java | 2 +-
.../latin/makedict/BinaryDictIOUtilsTests.java | 335 +++++++++++++++++++++
4 files changed, 639 insertions(+), 2 deletions(-)
create mode 100644 tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 096ca0992..e5ec449ea 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -27,12 +27,15 @@ import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Stack;
public final class BinaryDictIOUtils {
private static final boolean DBG = false;
+ private static final int MSB24 = 0x800000;
+ private static final int SINT24_MAX = 0x7FFFFF;
private static final int MAX_JUMPS = 10000;
private BinaryDictIOUtils() {
@@ -646,4 +649,302 @@ public final class BinaryDictIOUtils {
writeSInt24ToStream(destination, FormatSpec.NO_FORWARD_LINK_ADDRESS);
return size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
}
+
+ /**
+ * Move a group that is referred to by oldGroupOrigin to the tail of the file.
+ * And set the children address to the byte after the group.
+ *
+ * @param nodeOrigin the address of the tail of the file.
+ * @param characters
+ * @param length
+ * @param flags
+ * @param frequency
+ * @param parentAddress
+ * @param shortcutTargets
+ * @param bigrams
+ * @param destination the stream representing the tail of the file.
+ * @param buffer the buffer representing the (constant-size) body of the file.
+ * @param oldNodeOrigin
+ * @param oldGroupOrigin
+ * @param formatOptions
+ * @return the size written, in bytes.
+ * @throws IOException
+ */
+ private static int moveGroup(final int nodeOrigin, final int[] characters, final int length,
+ final int flags, final int frequency, final int parentAddress,
+ final ArrayList shortcutTargets,
+ final ArrayList bigrams, final OutputStream destination,
+ final FusionDictionaryBufferInterface buffer, final int oldNodeOrigin,
+ final int oldGroupOrigin, final FormatOptions formatOptions) throws IOException {
+ int size = 0;
+ final int newGroupOrigin = nodeOrigin + 1;
+ final int[] writtenCharacters = Arrays.copyOfRange(characters, 0, length);
+ final CharGroupInfo tmpInfo = new CharGroupInfo(newGroupOrigin, -1 /* endAddress */,
+ flags, writtenCharacters, frequency, parentAddress, FormatSpec.NO_CHILDREN_ADDRESS,
+ shortcutTargets, bigrams);
+ size = computeGroupSize(tmpInfo, formatOptions);
+ final CharGroupInfo newInfo = new CharGroupInfo(newGroupOrigin, newGroupOrigin + size,
+ flags, writtenCharacters, frequency, parentAddress,
+ nodeOrigin + 1 + size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE, shortcutTargets,
+ bigrams);
+ moveCharGroup(destination, buffer, newInfo, oldNodeOrigin, oldGroupOrigin, formatOptions);
+ return 1 + size + FormatSpec.FORWARD_LINK_ADDRESS_SIZE;
+ }
+
+ /**
+ * Insert a word into a binary dictionary.
+ *
+ * @param buffer
+ * @param destination
+ * @param word
+ * @param frequency
+ * @param bigramStrings
+ * @param shortcuts
+ * @throws IOException
+ * @throws UnsupportedFormatException
+ */
+ // TODO: Support batch insertion.
+ public static void insertWord(final FusionDictionaryBufferInterface buffer,
+ final OutputStream destination, final String word, final int frequency,
+ final ArrayList bigramStrings,
+ final ArrayList shortcuts, final boolean isNotAWord,
+ final boolean isBlackListEntry)
+ throws IOException, UnsupportedFormatException {
+ final ArrayList bigrams = new ArrayList();
+ if (bigramStrings != null) {
+ for (final WeightedString bigram : bigramStrings) {
+ int position = getTerminalPosition(buffer, bigram.mWord);
+ if (position == FormatSpec.NOT_VALID_WORD) {
+ // TODO: figure out what is the correct thing to do here.
+ } else {
+ bigrams.add(new PendingAttribute(position, bigram.mFrequency));
+ }
+ }
+ }
+
+ final boolean isTerminal = true;
+ final boolean hasBigrams = !bigrams.isEmpty();
+ final boolean hasShortcuts = shortcuts != null && !shortcuts.isEmpty();
+
+ // find the insert position of the word.
+ if (buffer.position() != 0) buffer.position(0);
+ final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
+
+ int wordPos = 0, address = buffer.position(), nodeOriginAddress = buffer.position();
+ final int[] codePoints = FusionDictionary.getCodePoints(word);
+ final int wordLen = codePoints.length;
+
+ for (int depth = 0; depth < Constants.Dictionary.MAX_WORD_LENGTH; ++depth) {
+ if (wordPos >= wordLen) break;
+ nodeOriginAddress = buffer.position();
+ int nodeParentAddress = -1;
+ final int charGroupCount = BinaryDictInputOutput.readCharGroupCount(buffer);
+ boolean foundNextGroup = false;
+
+ for (int i = 0; i < charGroupCount; ++i) {
+ address = buffer.position();
+ final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
+ buffer.position(), header.mFormatOptions);
+ final boolean isMovedGroup = BinaryDictInputOutput.isMovedGroup(currentInfo.mFlags,
+ header.mFormatOptions);
+ if (isMovedGroup) continue;
+ nodeParentAddress = (currentInfo.mParentAddress == FormatSpec.NO_PARENT_ADDRESS)
+ ? FormatSpec.NO_PARENT_ADDRESS : currentInfo.mParentAddress + address;
+ boolean matched = true;
+ for (int p = 0; p < currentInfo.mCharacters.length; ++p) {
+ if (wordPos + p >= wordLen) {
+ /*
+ * splitting
+ * before
+ * abcd - ef
+ *
+ * insert "abc"
+ *
+ * after
+ * abc - d - ef
+ */
+ final int newNodeAddress = buffer.limit();
+ final int flags = BinaryDictInputOutput.makeCharGroupFlags(p > 1,
+ isTerminal, 0, hasShortcuts, hasBigrams, false /* isNotAWord */,
+ false /* isBlackListEntry */, header.mFormatOptions);
+ int written = moveGroup(newNodeAddress, currentInfo.mCharacters, p, flags,
+ frequency, nodeParentAddress, shortcuts, bigrams, destination,
+ buffer, nodeOriginAddress, address, header.mFormatOptions);
+
+ final int[] characters2 = Arrays.copyOfRange(currentInfo.mCharacters, p,
+ currentInfo.mCharacters.length);
+ if (currentInfo.mChildrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ updateParentAddresses(buffer, currentInfo.mChildrenAddress,
+ newNodeAddress + written + 1, header.mFormatOptions);
+ }
+ final CharGroupInfo newInfo2 = new CharGroupInfo(
+ newNodeAddress + written + 1, -1 /* endAddress */,
+ currentInfo.mFlags, characters2, currentInfo.mFrequency,
+ newNodeAddress + 1, currentInfo.mChildrenAddress,
+ currentInfo.mShortcutTargets, currentInfo.mBigrams);
+ writeNode(destination, new CharGroupInfo[] { newInfo2 });
+ return;
+ } else if (codePoints[wordPos + p] != currentInfo.mCharacters[p]) {
+ if (p > 0) {
+ /*
+ * splitting
+ * before
+ * ab - cd
+ *
+ * insert "ac"
+ *
+ * after
+ * a - b - cd
+ * |
+ * - c
+ */
+
+ final int newNodeAddress = buffer.limit();
+ final int childrenAddress = currentInfo.mChildrenAddress;
+
+ // move prefix
+ final int prefixFlags = BinaryDictInputOutput.makeCharGroupFlags(p > 1,
+ false /* isTerminal */, 0 /* childrenAddressSize*/,
+ false /* hasShortcut */, false /* hasBigrams */,
+ false /* isNotAWord */, false /* isBlackListEntry */,
+ header.mFormatOptions);
+ int written = moveGroup(newNodeAddress, currentInfo.mCharacters, p,
+ prefixFlags, -1 /* frequency */, nodeParentAddress, null, null,
+ destination, buffer, nodeOriginAddress, address,
+ header.mFormatOptions);
+
+ final int[] suffixCharacters = Arrays.copyOfRange(
+ currentInfo.mCharacters, p, currentInfo.mCharacters.length);
+ if (currentInfo.mChildrenAddress != FormatSpec.NO_CHILDREN_ADDRESS) {
+ updateParentAddresses(buffer, currentInfo.mChildrenAddress,
+ newNodeAddress + written + 1, header.mFormatOptions);
+ }
+ final int suffixFlags = BinaryDictInputOutput.makeCharGroupFlags(
+ suffixCharacters.length > 1,
+ (currentInfo.mFlags & FormatSpec.FLAG_IS_TERMINAL) != 0,
+ 0 /* childrenAddressSize */,
+ (currentInfo.mFlags & FormatSpec.FLAG_HAS_SHORTCUT_TARGETS)
+ != 0,
+ (currentInfo.mFlags & FormatSpec.FLAG_HAS_BIGRAMS) != 0,
+ isNotAWord, isBlackListEntry, header.mFormatOptions);
+ final CharGroupInfo suffixInfo = new CharGroupInfo(
+ newNodeAddress + written + 1, -1 /* endAddress */, suffixFlags,
+ suffixCharacters, currentInfo.mFrequency, newNodeAddress + 1,
+ currentInfo.mChildrenAddress, currentInfo.mShortcutTargets,
+ currentInfo.mBigrams);
+ written += computeGroupSize(suffixInfo, header.mFormatOptions) + 1;
+
+ final int[] newCharacters = Arrays.copyOfRange(codePoints, wordPos + p,
+ codePoints.length);
+ final int flags = BinaryDictInputOutput.makeCharGroupFlags(
+ newCharacters.length > 1, isTerminal,
+ 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, header.mFormatOptions);
+ final CharGroupInfo newInfo = new CharGroupInfo(
+ newNodeAddress + written, -1 /* endAddress */, flags,
+ newCharacters, frequency, newNodeAddress + 1,
+ FormatSpec.NO_CHILDREN_ADDRESS, shortcuts, bigrams);
+ writeNode(destination, new CharGroupInfo[] { suffixInfo, newInfo });
+ return;
+ }
+ matched = false;
+ break;
+ }
+ }
+
+ if (matched) {
+ if (wordPos + currentInfo.mCharacters.length == wordLen) {
+ // the word exists in the dictionary.
+ // only update group.
+ final int newNodeAddress = buffer.limit();
+ final boolean hasMultipleChars = currentInfo.mCharacters.length > 1;
+ final int flags = BinaryDictInputOutput.makeCharGroupFlags(hasMultipleChars,
+ isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, header.mFormatOptions);
+ final CharGroupInfo newInfo = new CharGroupInfo(newNodeAddress + 1,
+ -1 /* endAddress */, flags, currentInfo.mCharacters, frequency,
+ nodeParentAddress, currentInfo.mChildrenAddress, shortcuts,
+ bigrams);
+ moveCharGroup(destination, buffer, newInfo, nodeOriginAddress, address,
+ header.mFormatOptions);
+ return;
+ }
+ wordPos += currentInfo.mCharacters.length;
+ if (currentInfo.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
+ /*
+ * found the prefix of the word.
+ * make new node and link to the node from this group.
+ *
+ * before
+ * ab - cd
+ *
+ * insert "abcde"
+ *
+ * after
+ * ab - cd - e
+ */
+ final int newNodeAddress = buffer.limit();
+ updateChildrenAddress(buffer, address, newNodeAddress,
+ header.mFormatOptions);
+ final int newGroupAddress = newNodeAddress + 1;
+ final boolean hasMultipleChars = (wordLen - wordPos) > 1;
+ final int flags = BinaryDictInputOutput.makeCharGroupFlags(hasMultipleChars,
+ isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, header.mFormatOptions);
+ final int[] characters = Arrays.copyOfRange(codePoints, wordPos, wordLen);
+ final CharGroupInfo newInfo = new CharGroupInfo(newGroupAddress, -1, flags,
+ characters, frequency, address, FormatSpec.NO_CHILDREN_ADDRESS,
+ shortcuts, bigrams);
+ writeNode(destination, new CharGroupInfo[] { newInfo });
+ return;
+ }
+ buffer.position(currentInfo.mChildrenAddress);
+ foundNextGroup = true;
+ break;
+ }
+ }
+
+ if (foundNextGroup) continue;
+
+ // reached the end of the array.
+ final int linkAddressPosition = buffer.position();
+ int nextLink = buffer.readUnsignedInt24();
+ if ((nextLink & MSB24) != 0) {
+ nextLink = -(nextLink & SINT24_MAX);
+ }
+ if (nextLink == FormatSpec.NO_FORWARD_LINK_ADDRESS) {
+ /*
+ * expand this node.
+ *
+ * before
+ * ab - cd
+ *
+ * insert "abef"
+ *
+ * after
+ * ab - cd
+ * |
+ * - ef
+ */
+
+ // change the forward link address.
+ final int newNodeAddress = buffer.limit();
+ buffer.position(linkAddressPosition);
+ writeSInt24ToBuffer(buffer, newNodeAddress);
+
+ final int[] characters = Arrays.copyOfRange(codePoints, wordPos, wordLen);
+ final int flags = BinaryDictInputOutput.makeCharGroupFlags(characters.length > 1,
+ isTerminal, 0 /* childrenAddressSize */, hasShortcuts, hasBigrams,
+ isNotAWord, isBlackListEntry, header.mFormatOptions);
+ final CharGroupInfo newInfo = new CharGroupInfo(newNodeAddress + 1,
+ -1 /* endAddress */, flags, characters, frequency, nodeParentAddress,
+ FormatSpec.NO_CHILDREN_ADDRESS, shortcuts, bigrams);
+ writeNode(destination, new CharGroupInfo[]{ newInfo });
+ return;
+ } else {
+ depth--;
+ buffer.position(nextLink);
+ }
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 624e72f0c..2d39094ff 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -411,7 +411,8 @@ public final class BinaryDictInputOutput {
* Helper method to check whether the group is moved.
*/
public static boolean isMovedGroup(final int flags, final FormatOptions options) {
- return options.mSupportsDynamicUpdate && ((flags & FormatSpec.FLAG_IS_MOVED) == 1);
+ return options.mSupportsDynamicUpdate
+ && ((flags & FormatSpec.MASK_GROUP_ADDRESS_TYPE) == FormatSpec.FLAG_IS_MOVED);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 3193ef457..6f1faa192 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -279,7 +279,7 @@ public final class FusionDictionary implements Iterable {
/**
* Helper method to convert a String to an int array.
*/
- static private int[] getCodePoints(final String word) {
+ static int[] getCodePoints(final String word) {
// TODO: this is a copy-paste of the contents of StringUtils.toCodePointArray,
// which is not visible from the makedict package. Factor this code.
final char[] characters = word.toCharArray();
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
new file mode 100644
index 000000000..7607b58eb
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2012 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.latin.makedict;
+
+import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.ByteBufferWrapper;
+import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.CharEncoding;
+import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
+import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
+import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.util.Log;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Random;
+
+public class BinaryDictIOUtilsTests extends AndroidTestCase{
+ private static final String TAG = BinaryDictIOUtilsTests.class.getSimpleName();
+ private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
+ new FormatSpec.FormatOptions(3, true);
+ private static final int MAX_UNIGRAMS = 1500;
+
+ private static final ArrayList sWords = CollectionUtils.newArrayList();
+
+ private static final String[] CHARACTERS = {
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
+ "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
+ "\u00FC" /* ü */, "\u00E2" /* â */, "\u00F1" /* ñ */, // accented characters
+ "\u4E9C" /* 亜 */, "\u4F0A" /* 伊 */, "\u5B87" /* 宇 */, // kanji
+ "\uD841\uDE28" /* 𠘨 */, "\uD840\uDC0B" /* 𠀋 */, "\uD861\uDeD7" /* 𨛗 */ // surrogate pair
+ };
+
+ public BinaryDictIOUtilsTests() {
+ super();
+ final Random random = new Random(123456);
+ sWords.clear();
+ for (int i = 0; i < MAX_UNIGRAMS; ++i) {
+ sWords.add(generateWord(random.nextInt()));
+ }
+ }
+
+ // Utilities for test
+ private String generateWord(final int value) {
+ final int lengthOfChars = CHARACTERS.length;
+ StringBuilder builder = new StringBuilder("");
+ long lvalue = Math.abs((long)value);
+ while (lvalue > 0) {
+ builder.append(CHARACTERS[(int)(lvalue % lengthOfChars)]);
+ lvalue /= lengthOfChars;
+ }
+ if (builder.toString().equals("")) return "a";
+ return builder.toString();
+ }
+
+ private static void printCharGroup(final CharGroupInfo info) {
+ Log.d(TAG, " CharGroup at " + info.mOriginalAddress);
+ Log.d(TAG, " flags = " + info.mFlags);
+ Log.d(TAG, " parentAddress = " + info.mParentAddress);
+ Log.d(TAG, " characters = " + new String(info.mCharacters, 0,
+ info.mCharacters.length));
+ if (info.mFrequency != -1) Log.d(TAG, " frequency = " + info.mFrequency);
+ if (info.mChildrenAddress == FormatSpec.NO_CHILDREN_ADDRESS) {
+ Log.d(TAG, " children address = no children address");
+ } else {
+ Log.d(TAG, " children address = " + info.mChildrenAddress);
+ }
+ if (info.mShortcutTargets != null) {
+ for (final WeightedString ws : info.mShortcutTargets) {
+ Log.d(TAG, " shortcuts = " + ws.mWord);
+ }
+ }
+ if (info.mBigrams != null) {
+ for (final PendingAttribute attr : info.mBigrams) {
+ Log.d(TAG, " bigram = " + attr.mAddress);
+ }
+ }
+ Log.d(TAG, " end address = " + info.mEndAddress);
+ }
+
+ private static void printNode(final FusionDictionaryBufferInterface buffer,
+ final FormatSpec.FormatOptions formatOptions) {
+ Log.d(TAG, "Node at " + buffer.position());
+ final int count = BinaryDictInputOutput.readCharGroupCount(buffer);
+ Log.d(TAG, " charGroupCount = " + count);
+ for (int i = 0; i < count; ++i) {
+ final CharGroupInfo currentInfo = BinaryDictInputOutput.readCharGroup(buffer,
+ buffer.position(), formatOptions);
+ printCharGroup(currentInfo);
+ }
+ if (formatOptions.mSupportsDynamicUpdate) {
+ final int forwardLinkAddress = buffer.readUnsignedInt24();
+ Log.d(TAG, " forwardLinkAddress = " + forwardLinkAddress);
+ }
+ }
+
+ private static void printBinaryFile(final FusionDictionaryBufferInterface buffer)
+ throws IOException, UnsupportedFormatException {
+ FileHeader header = BinaryDictInputOutput.readHeader(buffer);
+ while (buffer.position() < buffer.limit()) {
+ printNode(buffer, header.mFormatOptions);
+ }
+ }
+
+ private int getWordPosition(final File file, final String word) {
+ int position = FormatSpec.NOT_VALID_WORD;
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(file);
+ final FusionDictionaryBufferInterface buffer = new ByteBufferWrapper(
+ inStream.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()));
+ position = BinaryDictIOUtils.getTerminalPosition(buffer, word);
+ } catch (IOException e) {
+ } catch (UnsupportedFormatException e) {
+ } finally {
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ return position;
+ }
+
+ // return amount of time to insert a word
+ private long insertAndCheckWord(final File file, final String word, final int frequency,
+ final boolean exist) {
+ RandomAccessFile raFile = null;
+ FileOutputStream outStream = null;
+ FusionDictionaryBufferInterface buffer = null;
+ long amountOfTime = -1;
+ try {
+ raFile = new RandomAccessFile(file, "rw");
+ buffer = new ByteBufferWrapper(raFile.getChannel().map(
+ FileChannel.MapMode.READ_WRITE, 0, file.length()));
+ outStream = new FileOutputStream(file, true);
+
+ if (!exist) {
+ assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
+ }
+ final long now = System.nanoTime();
+ BinaryDictIOUtils.insertWord(buffer, outStream, word, frequency, null, null, false,
+ false);
+ amountOfTime = System.nanoTime() - now;
+ MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
+ outStream.close();
+ raFile.close();
+ } catch (IOException e) {
+ } catch (UnsupportedFormatException e) {
+ } finally {
+ if (outStream != null) {
+ try {
+ outStream.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ if (raFile != null) {
+ try {
+ raFile.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ return amountOfTime;
+ }
+
+ private void deleteWord(final File file, final String word) {
+ RandomAccessFile raFile = null;
+ FusionDictionaryBufferInterface buffer = null;
+ try {
+ raFile = new RandomAccessFile(file, "rw");
+ buffer = new ByteBufferWrapper(raFile.getChannel().map(
+ FileChannel.MapMode.READ_WRITE, 0, file.length()));
+ BinaryDictIOUtils.deleteWord(buffer, word);
+ } catch (IOException e) {
+ } catch (UnsupportedFormatException e) {
+ } finally {
+ if (raFile != null) {
+ try {
+ raFile.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+
+
+
+ private void checkReverseLookup(final File file, final String word, final int position) {
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(file);
+ final FusionDictionaryBufferInterface buffer = new ByteBufferWrapper(
+ inStream.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()));
+ final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
+ assertEquals(word, BinaryDictInputOutput.getWordAtAddress(buffer, header.mHeaderSize,
+ position - header.mHeaderSize, header.mFormatOptions));
+ } catch (IOException e) {
+ } catch (UnsupportedFormatException e) {
+ } finally {
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+
+ public void testInsertWord() {
+ File file = null;
+ try {
+ file = File.createTempFile("testInsertWord", ".dict");
+ } catch (IOException e) {
+ fail("IOException while creating temporary file: " + e);
+ }
+
+ // set an initial dictionary.
+ final FusionDictionary dict = new FusionDictionary(new Node(),
+ new FusionDictionary.DictionaryOptions(new HashMap(), false, false));
+ dict.add("abcd", 10, null, false);
+
+ try {
+ final FileOutputStream out = new FileOutputStream(file);
+ BinaryDictInputOutput.writeDictionaryBinary(out, dict, FORMAT_OPTIONS);
+ out.close();
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ } catch (UnsupportedFormatException e) {
+ fail("UnsupportedFormatException while writing an initial dictionary : " + e);
+ }
+
+ MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
+ insertAndCheckWord(file, "abcde", 10, false);
+
+ insertAndCheckWord(file, "abcdefghijklmn", 10, false);
+ checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn"));
+
+ insertAndCheckWord(file, "abcdabcd", 10, false);
+ checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd"));
+
+ // update the existing word.
+ insertAndCheckWord(file, "abcdabcd", 15, true);
+
+ // split 1
+ insertAndCheckWord(file, "ab", 20, false);
+
+ // split 2
+ insertAndCheckWord(file, "ami", 30, false);
+
+ deleteWord(file, "ami");
+ assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "ami"));
+
+ insertAndCheckWord(file, "abcdabfg", 30, false);
+
+ deleteWord(file, "abcd");
+ assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
+ }
+
+ public void testRandomWords() {
+ File file = null;
+ try {
+ file = File.createTempFile("testRandomWord", ".dict");
+ } catch (IOException e) {
+ }
+ assertNotNull(file);
+
+ // set an initial dictionary.
+ final FusionDictionary dict = new FusionDictionary(new Node(),
+ new FusionDictionary.DictionaryOptions(new HashMap(), false,
+ false));
+ dict.add("initial", 10, null, false);
+
+ try {
+ final FileOutputStream out = new FileOutputStream(file);
+ BinaryDictInputOutput.writeDictionaryBinary(out, dict, FORMAT_OPTIONS);
+ out.close();
+ } catch (IOException e) {
+ assertTrue(false);
+ } catch (UnsupportedFormatException e) {
+ assertTrue(false);
+ }
+
+ long maxTimeToInsert = 0, sum = 0;
+ long minTimeToInsert = 100000000; // 1000000000 is an upper bound for minTimeToInsert.
+ int cnt = 0;
+ for (final String word : sWords) {
+ final long diff = insertAndCheckWord(file, word, cnt%255, false);
+ maxTimeToInsert = Math.max(maxTimeToInsert, diff);
+ minTimeToInsert = Math.min(minTimeToInsert, diff);
+ sum += diff;
+ cnt++;
+ }
+ cnt = 0;
+ for (final String word : sWords) {
+ MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
+ }
+
+ Log.d(TAG, "max = " + ((double)maxTimeToInsert/1000000) + " ms.");
+ Log.d(TAG, "min = " + ((double)minTimeToInsert/1000000) + " ms.");
+ Log.d(TAG, "avg = " + ((double)sum/MAX_UNIGRAMS/1000000) + " ms.");
+ }
+}
--
cgit v1.2.3-83-g751a
From 2699b45dbc22b56d57690fcc8b4592e0371b8710 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Thu, 4 Oct 2012 15:33:41 +0900
Subject: Always consider a new line the start of a sentence
Bug: 7282523
Change-Id: I10a73e99efdfe6acb9a16819694b98c6714fd451
---
java/src/com/android/inputmethod/latin/StringUtils.java | 14 +++++++++-----
.../com/android/inputmethod/latin/StringUtilsTests.java | 8 ++++++++
2 files changed, 17 insertions(+), 5 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java
index 7b65b7343..df7709892 100644
--- a/java/src/com/android/inputmethod/latin/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/StringUtils.java
@@ -250,15 +250,19 @@ public final class StringUtils {
// Step 3 : Search for the start of a paragraph. From the starting point computed in step 2,
// we go back over any space or tab char sitting there. We find the start of a paragraph
- // if the first char that's not a space or tab is a start of line (as in, either \n or
- // start of text).
+ // if the first char that's not a space or tab is a start of line (as in \n, start of text,
+ // or some other similar characters).
int j = i;
+ char prevChar = Keyboard.CODE_SPACE;
if (hasSpaceBefore) --j;
- while (j > 0 && Character.isWhitespace(cs.charAt(j - 1))) {
+ while (j > 0) {
+ prevChar = cs.charAt(j - 1);
+ if (!Character.isSpaceChar(prevChar) && prevChar != Keyboard.CODE_TAB) break;
j--;
}
- if (j == 0) {
- // There is only whitespace between the start of the text and the cursor. Both
+ if (j <= 0 || Character.isWhitespace(prevChar)) {
+ // There are only spacing chars between the start of the paragraph and the cursor,
+ // defined as a isWhitespace() char that is neither a isSpaceChar() nor a tab. Both
// MODE_WORDS and MODE_SENTENCES should be active.
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS
| TextUtils.CAP_MODE_SENTENCES) & reqModes;
diff --git a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java b/tests/src/com/android/inputmethod/latin/StringUtilsTests.java
index be3494dc7..3142bd602 100644
--- a/tests/src/com/android/inputmethod/latin/StringUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/StringUtilsTests.java
@@ -140,6 +140,14 @@ public class StringUtilsTests extends AndroidTestCase {
allPathsForCaps("Word", c | w, l, true);
allPathsForCaps("Word.", c | w | s, l, true);
+ // Tests after some whitespace
+ allPathsForCaps("Word\n", c | w | s, l, false);
+ allPathsForCaps("Word\n", c | w | s, l, true);
+ allPathsForCaps("Word\n ", c | w | s, l, true);
+ allPathsForCaps("Word.\n", c | w | s, l, false);
+ allPathsForCaps("Word.\n", c | w | s, l, true);
+ allPathsForCaps("Word.\n ", c | w | s, l, true);
+
l = Locale.FRENCH;
allPathsForCaps("\"Word.\" ", c | w, l, false);
allPathsForCaps("\"Word\". ", c | w | s, l, false);
--
cgit v1.2.3-83-g751a
From d2579c4832325bb703e275674706886dce50915d Mon Sep 17 00:00:00 2001
From: Yuichiro Hanada
Date: Fri, 5 Oct 2012 11:43:21 +0900
Subject: fix writeCharGroup.
Change-Id: Ib841afaba0a20c3b300eb7d3e9133243f9f3ae58
---
.../latin/makedict/BinaryDictIOUtils.java | 29 ++++++-
.../latin/makedict/BinaryDictIOUtilsTests.java | 98 ++++++++++++++++++----
2 files changed, 106 insertions(+), 21 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index e5ec449ea..40e089f3a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -535,10 +535,13 @@ public final class BinaryDictIOUtils {
// TODO: Consolidate this code with the code that computes the size of the bigram list
// in BinaryDictionaryInputOutput#computeActualNodeSize
for (int i = 0; i < info.mBigrams.size(); ++i) {
- final int bigramOffset = info.mBigrams.get(i).mAddress - info.mOriginalAddress;
+
final int bigramFrequency = info.mBigrams.get(i).mFrequency;
int bigramFlags = (i < info.mBigrams.size() - 1)
? FormatSpec.FLAG_ATTRIBUTE_HAS_NEXT : 0;
+ size++;
+ final int bigramOffset = info.mBigrams.get(i).mAddress - (info.mOriginalAddress
+ + size);
bigramFlags |= (bigramOffset < 0) ? FormatSpec.FLAG_ATTRIBUTE_OFFSET_NEGATIVE : 0;
switch (BinaryDictInputOutput.getByteSize(bigramOffset)) {
case 1:
@@ -553,7 +556,6 @@ public final class BinaryDictIOUtils {
}
bigramFlags |= bigramFrequency & FormatSpec.FLAG_ATTRIBUTE_FREQUENCY;
destination.write((byte)bigramFlags);
- size++;
size += writeVariableAddress(destination, Math.abs(bigramOffset));
}
}
@@ -717,7 +719,7 @@ public final class BinaryDictIOUtils {
if (position == FormatSpec.NOT_VALID_WORD) {
// TODO: figure out what is the correct thing to do here.
} else {
- bigrams.add(new PendingAttribute(position, bigram.mFrequency));
+ bigrams.add(new PendingAttribute(bigram.mFrequency, position));
}
}
}
@@ -947,4 +949,25 @@ public final class BinaryDictIOUtils {
}
}
}
+
+ /**
+ * Find a word from the buffer.
+ *
+ * @param buffer the buffer representing the body of the dictionary file.
+ * @param word the word searched
+ * @return the found group
+ * @throws IOException
+ * @throws UnsupportedFormatException
+ */
+ public static CharGroupInfo findWordFromBuffer(final FusionDictionaryBufferInterface buffer,
+ final String word) throws IOException, UnsupportedFormatException {
+ int position = getTerminalPosition(buffer, word);
+ if (position != FormatSpec.NOT_VALID_WORD) {
+ buffer.position(0);
+ final FileHeader header = BinaryDictInputOutput.readHeader(buffer);
+ buffer.position(position);
+ return BinaryDictInputOutput.readCharGroup(buffer, position, header.mFormatOptions);
+ }
+ return null;
+ }
}
diff --git a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
index 7607b58eb..318516845 100644
--- a/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtilsTests.java
@@ -28,6 +28,7 @@ import android.test.AndroidTestCase;
import android.test.MoreAsserts;
import android.util.Log;
+import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
@@ -41,7 +42,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.Random;
-public class BinaryDictIOUtilsTests extends AndroidTestCase{
+public class BinaryDictIOUtilsTests extends AndroidTestCase {
private static final String TAG = BinaryDictIOUtilsTests.class.getSimpleName();
private static final FormatSpec.FormatOptions FORMAT_OPTIONS =
new FormatSpec.FormatOptions(3, true);
@@ -150,26 +151,50 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase{
return position;
}
+ private CharGroupInfo findWordFromFile(final File file, final String word) {
+ FileInputStream inStream = null;
+ CharGroupInfo info = null;
+ try {
+ inStream = new FileInputStream(file);
+ final FusionDictionaryBufferInterface buffer = new ByteBufferWrapper(
+ inStream.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()));
+ info = BinaryDictIOUtils.findWordFromBuffer(buffer, word);
+ } catch (IOException e) {
+ } catch (UnsupportedFormatException e) {
+ } finally {
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ return info;
+ }
+
// return amount of time to insert a word
private long insertAndCheckWord(final File file, final String word, final int frequency,
- final boolean exist) {
+ final boolean exist, final ArrayList bigrams,
+ final ArrayList shortcuts) {
RandomAccessFile raFile = null;
- FileOutputStream outStream = null;
+ BufferedOutputStream outStream = null;
FusionDictionaryBufferInterface buffer = null;
long amountOfTime = -1;
try {
raFile = new RandomAccessFile(file, "rw");
buffer = new ByteBufferWrapper(raFile.getChannel().map(
FileChannel.MapMode.READ_WRITE, 0, file.length()));
- outStream = new FileOutputStream(file, true);
+ outStream = new BufferedOutputStream(new FileOutputStream(file, true));
if (!exist) {
assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
}
final long now = System.nanoTime();
- BinaryDictIOUtils.insertWord(buffer, outStream, word, frequency, null, null, false,
- false);
+ BinaryDictIOUtils.insertWord(buffer, outStream, word, frequency, bigrams, shortcuts,
+ false, false);
amountOfTime = System.nanoTime() - now;
+ outStream.flush();
MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, word));
outStream.close();
raFile.close();
@@ -215,8 +240,6 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase{
}
}
-
-
private void checkReverseLookup(final File file, final String word, final int position) {
FileInputStream inStream = null;
try {
@@ -242,7 +265,7 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase{
public void testInsertWord() {
File file = null;
try {
- file = File.createTempFile("testInsertWord", ".dict");
+ file = File.createTempFile("testInsertWord", ".dict", getContext().getCacheDir());
} catch (IOException e) {
fail("IOException while creating temporary file: " + e);
}
@@ -263,36 +286,74 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase{
}
MoreAsserts.assertNotEqual(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
- insertAndCheckWord(file, "abcde", 10, false);
+ insertAndCheckWord(file, "abcde", 10, false, null, null);
- insertAndCheckWord(file, "abcdefghijklmn", 10, false);
+ insertAndCheckWord(file, "abcdefghijklmn", 10, false, null, null);
checkReverseLookup(file, "abcdefghijklmn", getWordPosition(file, "abcdefghijklmn"));
- insertAndCheckWord(file, "abcdabcd", 10, false);
+ insertAndCheckWord(file, "abcdabcd", 10, false, null, null);
checkReverseLookup(file, "abcdabcd", getWordPosition(file, "abcdabcd"));
// update the existing word.
- insertAndCheckWord(file, "abcdabcd", 15, true);
+ insertAndCheckWord(file, "abcdabcd", 15, true, null, null);
// split 1
- insertAndCheckWord(file, "ab", 20, false);
+ insertAndCheckWord(file, "ab", 20, false, null, null);
// split 2
- insertAndCheckWord(file, "ami", 30, false);
+ insertAndCheckWord(file, "ami", 30, false, null, null);
deleteWord(file, "ami");
assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "ami"));
- insertAndCheckWord(file, "abcdabfg", 30, false);
+ insertAndCheckWord(file, "abcdabfg", 30, false, null, null);
deleteWord(file, "abcd");
assertEquals(FormatSpec.NOT_VALID_WORD, getWordPosition(file, "abcd"));
}
+ public void testInsertWordWithBigrams() {
+ File file = null;
+ try {
+ file = File.createTempFile("testInsertWordWithBigrams", ".dict",
+ getContext().getCacheDir());
+ } catch (IOException e) {
+ fail("IOException while creating temporary file: " + e);
+ }
+
+ // set an initial dictionary.
+ final FusionDictionary dict = new FusionDictionary(new Node(),
+ new FusionDictionary.DictionaryOptions(new HashMap(), false, false));
+ dict.add("abcd", 10, null, false);
+ dict.add("efgh", 15, null, false);
+
+ try {
+ final FileOutputStream out = new FileOutputStream(file);
+ BinaryDictInputOutput.writeDictionaryBinary(out, dict, FORMAT_OPTIONS);
+ out.close();
+ } catch (IOException e) {
+ fail("IOException while writing an initial dictionary : " + e);
+ } catch (UnsupportedFormatException e) {
+ fail("UnsupportedFormatException while writing an initial dictionary : " + e);
+ }
+
+ final ArrayList banana = new ArrayList();
+ banana.add(new WeightedString("banana", 10));
+
+ insertAndCheckWord(file, "banana", 0, false, null, null);
+ insertAndCheckWord(file, "recursive", 60, true, banana, null);
+
+ final CharGroupInfo info = findWordFromFile(file, "recursive");
+ int bananaPos = getWordPosition(file, "banana");
+ assertNotNull(info.mBigrams);
+ assertEquals(info.mBigrams.size(), 1);
+ assertEquals(info.mBigrams.get(0).mAddress, bananaPos);
+ }
+
public void testRandomWords() {
File file = null;
try {
- file = File.createTempFile("testRandomWord", ".dict");
+ file = File.createTempFile("testRandomWord", ".dict", getContext().getCacheDir());
} catch (IOException e) {
}
assertNotNull(file);
@@ -317,7 +378,8 @@ public class BinaryDictIOUtilsTests extends AndroidTestCase{
long minTimeToInsert = 100000000; // 1000000000 is an upper bound for minTimeToInsert.
int cnt = 0;
for (final String word : sWords) {
- final long diff = insertAndCheckWord(file, word, cnt%255, false);
+ final long diff = insertAndCheckWord(file, word,
+ cnt % FormatSpec.MAX_TERMINAL_FREQUENCY, false, null, null);
maxTimeToInsert = Math.max(maxTimeToInsert, diff);
minTimeToInsert = Math.min(minTimeToInsert, diff);
sum += diff;
--
cgit v1.2.3-83-g751a
From 792980d4aa4d0d91a5acfcbaba3f4471f1d2c073 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Fri, 5 Oct 2012 18:29:06 +0900
Subject: Avoid calling switchToLastInputMethod when other IMEs are in effect
(DO NOT MERGE)
Bug: 7299050
Change-Id: Ife6721a5fcbc4872bd36ffd8a8b81b04d73aebec
---
java/src/com/android/inputmethod/latin/LatinIME.java | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index fe6ad4901..d98966e96 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1219,22 +1219,25 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mConnection.performEditorAction(actionId);
}
+ // TODO: Revise the language switch key behavior to make it much smarter and more reasonable.
private void handleLanguageSwitchKey() {
- final boolean includesOtherImes = mCurrentSettings.mIncludesOtherImesInLanguageSwitchList;
final IBinder token = getWindow().getWindow().getAttributes().token;
+ if (mCurrentSettings.mIncludesOtherImesInLanguageSwitchList) {
+ mImm.switchToNextInputMethod(token, false /* onlyCurrentIme */);
+ return;
+ }
if (mShouldSwitchToLastSubtype) {
final InputMethodSubtype lastSubtype = mImm.getLastInputMethodSubtype();
final boolean lastSubtypeBelongsToThisIme =
ImfUtils.checkIfSubtypeBelongsToThisImeAndEnabled(this, lastSubtype);
- if ((includesOtherImes || lastSubtypeBelongsToThisIme)
- && mImm.switchToLastInputMethod(token)) {
+ if (lastSubtypeBelongsToThisIme && mImm.switchToLastInputMethod(token)) {
mShouldSwitchToLastSubtype = false;
} else {
- mImm.switchToNextInputMethod(token, !includesOtherImes);
+ mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */);
mShouldSwitchToLastSubtype = true;
}
} else {
- mImm.switchToNextInputMethod(token, !includesOtherImes);
+ mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */);
}
}
--
cgit v1.2.3-83-g751a
From fc62882591e9a6f25105b9d67db62469b0043348 Mon Sep 17 00:00:00 2001
From: Ken Wakasa
Date: Sun, 7 Oct 2012 12:05:23 +0900
Subject: Fix a small typo
Change-Id: I813d97b9453f8aa7aae99bd165336b1e5a81dc6a
---
java/src/com/android/inputmethod/latin/LatinIME.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c0938cf97..5a6a50238 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1230,7 +1230,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final InputMethodSubtype lastSubtype = mImm.getLastInputMethodSubtype();
final boolean lastSubtypeBelongsToThisIme =
ImfUtils.checkIfSubtypeBelongsToThisImeAndEnabled(this, lastSubtype);
- if (lastSubtypeBelongsToThisIme && mImm.switchToLastInputMethod(token)) {
+ if (lastSubtypeBelongsToThisIme && mImm.switchToLastInputMethod(token)) {
mShouldSwitchToLastSubtype = false;
} else {
mImm.switchToNextInputMethod(token, true /* onlyCurrentIme */);
--
cgit v1.2.3-83-g751a
From b02ee3d67a1884b6ff59cc16c29a476845c0694f Mon Sep 17 00:00:00 2001
From: Ken Wakasa
Date: Mon, 8 Oct 2012 11:46:14 +0900
Subject: Make use of the NELEMS and KEYCODE_SPACE macro. Also, remove an
unused parameter.
Change-Id: I3c7e6c59990c92b0d5e2fb80493e8673cdd37b09
---
.../inputmethod/latin/BinaryDictionary.java | 12 ++++-------
..._android_inputmethod_keyboard_ProximityInfo.cpp | 6 +++---
..._android_inputmethod_latin_BinaryDictionary.cpp | 12 +++++------
...ndroid_inputmethod_latin_DicTraverseSession.cpp | 4 ++--
native/jni/src/char_utils.cpp | 7 +++----
native/jni/src/correction.cpp | 2 +-
native/jni/src/correction.h | 1 -
native/jni/src/defines.h | 6 ++++--
native/jni/src/dictionary.cpp | 7 +++----
native/jni/src/dictionary.h | 4 ++--
native/jni/src/proximity_info_state.cpp | 2 +-
native/jni/src/unigram_dictionary.cpp | 24 ++++++++--------------
native/jni/src/unigram_dictionary.h | 5 ++---
13 files changed, 39 insertions(+), 53 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 7184f1d8a..9c48aa1a4 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -31,7 +31,7 @@ import java.util.Locale;
* Implements a static, compacted, binary dictionary of standard words.
*/
public final class BinaryDictionary extends Dictionary {
-
+ private static final String TAG = BinaryDictionary.class.getSimpleName();
public static final String DICTIONARY_PACK_AUTHORITY =
"com.android.inputmethod.latin.dictionarypack";
@@ -45,12 +45,9 @@ public final class BinaryDictionary extends Dictionary {
public static final int MAX_WORDS = 18;
public static final int MAX_SPACES = 16;
- private static final String TAG = BinaryDictionary.class.getSimpleName();
private static final int MAX_PREDICTIONS = 60;
private static final int MAX_RESULTS = Math.max(MAX_PREDICTIONS, MAX_WORDS);
- private static final int TYPED_LETTER_MULTIPLIER = 2;
-
private long mNativeDict;
private final Locale mLocale;
private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
@@ -106,8 +103,7 @@ public final class BinaryDictionary extends Dictionary {
}
private native long openNative(String sourceDir, long dictOffset, long dictSize,
- int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords,
- int maxPredictions);
+ int fullWordMultiplier, int maxWordLength, int maxWords, int maxPredictions);
private native void closeNative(long dict);
private native int getFrequencyNative(long dict, int[] word);
private native boolean isValidBigramNative(long dict, int[] word1, int[] word2);
@@ -121,8 +117,8 @@ public final class BinaryDictionary extends Dictionary {
// TODO: Move native dict into session
private final void loadDictionary(String path, long startOffset, long length) {
- mNativeDict = openNative(path, startOffset, length, TYPED_LETTER_MULTIPLIER,
- FULL_WORD_SCORE_MULTIPLIER, MAX_WORD_LENGTH, MAX_WORDS, MAX_PREDICTIONS);
+ mNativeDict = openNative(path, startOffset, length, FULL_WORD_SCORE_MULTIPLIER,
+ MAX_WORD_LENGTH, MAX_WORDS, MAX_PREDICTIONS);
}
@Override
diff --git a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
index 560b3a533..2423bb53b 100644
--- a/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
+++ b/native/jni/com_android_inputmethod_keyboard_ProximityInfo.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "LatinIME: jni: ProximityInfo"
#include "com_android_inputmethod_keyboard_ProximityInfo.h"
+#include "defines.h"
#include "jni.h"
#include "jni_common.h"
#include "proximity_info.h"
@@ -41,7 +42,7 @@ static void latinime_Keyboard_release(JNIEnv *env, jobject object, jlong proximi
delete pi;
}
-static JNINativeMethod sKeyboardMethods[] = {
+static JNINativeMethod sMethods[] = {
{"setProximityInfoNative", "(Ljava/lang/String;IIIIII[II[I[I[I[I[I[F[F[F)J",
reinterpret_cast(latinime_Keyboard_setProximityInfo)},
{"releaseProximityInfoNative", "(J)V", reinterpret_cast(latinime_Keyboard_release)}
@@ -49,7 +50,6 @@ static JNINativeMethod sKeyboardMethods[] = {
int register_ProximityInfo(JNIEnv *env) {
const char *const kClassPathName = "com/android/inputmethod/keyboard/ProximityInfo";
- return registerNativeMethods(env, kClassPathName, sKeyboardMethods,
- sizeof(sKeyboardMethods) / sizeof(sKeyboardMethods[0]));
+ return registerNativeMethods(env, kClassPathName, sMethods, NELEMS(sMethods));
}
} // namespace latinime
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index dd2513f9f..42f7da9d3 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -44,9 +44,8 @@ class ProximityInfo;
static void releaseDictBuf(const void *dictBuf, const size_t length, const int fd);
static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
- jstring sourceDir, jlong dictOffset, jlong dictSize,
- jint typedLetterMultiplier, jint fullWordMultiplier, jint maxWordLength, jint maxWords,
- jint maxPredictions) {
+ jstring sourceDir, jlong dictOffset, jlong dictSize, jint fullWordMultiplier,
+ jint maxWordLength, jint maxWords, jint maxPredictions) {
PROF_OPEN;
PROF_START(66);
const jsize sourceDirUtf8Length = env->GetStringUTFLength(sourceDir);
@@ -121,7 +120,7 @@ static jlong latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
#endif // USE_MMAP_FOR_DICTIONARY
} else {
dictionary = new Dictionary(dictBuf, static_cast(dictSize), fd, adjust,
- typedLetterMultiplier, fullWordMultiplier, maxWordLength, maxWords, maxPredictions);
+ fullWordMultiplier, maxWordLength, maxWords, maxPredictions);
}
PROF_END(66);
PROF_CLOSE;
@@ -277,7 +276,7 @@ static void releaseDictBuf(const void *dictBuf, const size_t length, const int f
}
static JNINativeMethod sMethods[] = {
- {"openNative", "(Ljava/lang/String;JJIIIII)J",
+ {"openNative", "(Ljava/lang/String;JJIIII)J",
reinterpret_cast(latinime_BinaryDictionary_open)},
{"closeNative", "(J)V", reinterpret_cast(latinime_BinaryDictionary_close)},
{"getSuggestionsNative", "(JJJ[I[I[I[I[IIIZ[IZ[C[I[I[I)I",
@@ -294,7 +293,6 @@ static JNINativeMethod sMethods[] = {
int register_BinaryDictionary(JNIEnv *env) {
const char *const kClassPathName = "com/android/inputmethod/latin/BinaryDictionary";
- return registerNativeMethods(env, kClassPathName, sMethods,
- sizeof(sMethods) / sizeof(sMethods[0]));
+ return registerNativeMethods(env, kClassPathName, sMethods, NELEMS(sMethods));
}
} // namespace latinime
diff --git a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
index 5d405f117..7bb8dc56e 100644
--- a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "LatinIME: jni: Session"
#include "com_android_inputmethod_latin_DicTraverseSession.h"
+#include "defines.h"
#include "dic_traverse_wrapper.h"
#include "jni.h"
#include "jni_common.h"
@@ -57,7 +58,6 @@ static JNINativeMethod sMethods[] = {
int register_DicTraverseSession(JNIEnv *env) {
const char *const kClassPathName = "com/android/inputmethod/latin/DicTraverseSession";
- return registerNativeMethods(env, kClassPathName, sMethods,
- sizeof(sMethods) / sizeof(sMethods[0]));
+ return registerNativeMethods(env, kClassPathName, sMethods, NELEMS(sMethods));
}
} // namespace latinime
diff --git a/native/jni/src/char_utils.cpp b/native/jni/src/char_utils.cpp
index d0547a982..9d27cadad 100644
--- a/native/jni/src/char_utils.cpp
+++ b/native/jni/src/char_utils.cpp
@@ -17,6 +17,7 @@
#include
#include "char_utils.h"
+#include "defines.h"
namespace latinime {
@@ -33,7 +34,7 @@ struct LatinCapitalSmallPair {
//
// unsigned short c, cc, ccc, ccc2;
// for (c = 0; c < 0xFFFF ; c++) {
-// if (c < sizeof(BASE_CHARS) / sizeof(BASE_CHARS[0])) {
+// if (c < NELEMS(BASE_CHARS)) {
// cc = BASE_CHARS[c];
// } else {
// cc = c;
@@ -894,9 +895,7 @@ static int compare_pair_capital(const void *a, const void *b) {
unsigned short latin_tolower(const unsigned short c) {
struct LatinCapitalSmallPair *p =
static_cast(bsearch(&c, SORTED_CHAR_MAP,
- sizeof(SORTED_CHAR_MAP) / sizeof(SORTED_CHAR_MAP[0]),
- sizeof(SORTED_CHAR_MAP[0]),
- compare_pair_capital));
+ NELEMS(SORTED_CHAR_MAP), sizeof(SORTED_CHAR_MAP[0]), compare_pair_capital));
return p ? p->small : c;
}
} // namespace latinime
diff --git a/native/jni/src/correction.cpp b/native/jni/src/correction.cpp
index 524abe9a1..d57b0e370 100644
--- a/native/jni/src/correction.cpp
+++ b/native/jni/src/correction.cpp
@@ -1118,7 +1118,7 @@ float Correction::RankingAlgorithm::calcNormalizedScore(const unsigned short *be
const int distance = editDistance(before, beforeLength, after, afterLength);
int spaceCount = 0;
for (int i = 0; i < afterLength; ++i) {
- if (after[i] == CODE_SPACE) {
+ if (after[i] == KEYCODE_SPACE) {
++spaceCount;
}
}
diff --git a/native/jni/src/correction.h b/native/jni/src/correction.h
index f016d5453..a099853e6 100644
--- a/native/jni/src/correction.h
+++ b/native/jni/src/correction.h
@@ -116,7 +116,6 @@ class Correction {
static int editDistance(const unsigned short *before,
const int beforeLength, const unsigned short *after, const int afterLength);
private:
- static const int CODE_SPACE = ' ';
static const int MAX_INITIAL_SCORE = 255;
};
diff --git a/native/jni/src/defines.h b/native/jni/src/defines.h
index ea0f0ef70..1bb031312 100644
--- a/native/jni/src/defines.h
+++ b/native/jni/src/defines.h
@@ -344,8 +344,8 @@ static inline void prof_out(void) {
#define MULTIPLE_WORDS_DEMOTION_RATE 80
#define MIN_INPUT_LENGTH_FOR_THREE_OR_MORE_WORDS_CORRECTION 6
-#define TWO_WORDS_CORRECTION_WITH_OTHER_ERROR_THRESHOLD 0.35
-#define START_TWO_WORDS_CORRECTION_THRESHOLD 0.185
+#define TWO_WORDS_CORRECTION_WITH_OTHER_ERROR_THRESHOLD 0.35f
+#define START_TWO_WORDS_CORRECTION_THRESHOLD 0.185f
/* heuristic... This should be changed if we change the unit of the frequency. */
#define SUPPRESS_SHORT_MULTIPLE_WORDS_THRESHOLD_FREQ (MAX_FREQ * 58 / 100)
@@ -392,6 +392,8 @@ static inline void prof_out(void) {
template inline T min(T a, T b) { return a < b ? a : b; }
template inline T max(T a, T b) { return a > b ? a : b; }
+#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
+
// The ratio of neutral area radius to sweet spot radius.
#define NEUTRAL_AREA_RADIUS_RATIO 1.3f
diff --git a/native/jni/src/dictionary.cpp b/native/jni/src/dictionary.cpp
index 2fbe83e86..81789ccfc 100644
--- a/native/jni/src/dictionary.cpp
+++ b/native/jni/src/dictionary.cpp
@@ -30,13 +30,12 @@ namespace latinime {
// TODO: Change the type of all keyCodes to uint32_t
Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust,
- int typedLetterMultiplier, int fullWordMultiplier, int maxWordLength, int maxWords,
- int maxPredictions)
+ int fullWordMultiplier, int maxWordLength, int maxWords, int maxPredictions)
: mDict(static_cast(dict)),
mOffsetDict((static_cast(dict)) + BinaryFormat::getHeaderSize(mDict)),
mDictSize(dictSize), mMmapFd(mmapFd), mDictBufAdjust(dictBufAdjust),
- mUnigramDictionary(new UnigramDictionary(mOffsetDict, typedLetterMultiplier,
- fullWordMultiplier, maxWordLength, maxWords, BinaryFormat::getFlags(mDict))),
+ mUnigramDictionary(new UnigramDictionary(mOffsetDict, fullWordMultiplier, maxWordLength,
+ maxWords, BinaryFormat::getFlags(mDict))),
mBigramDictionary(new BigramDictionary(mOffsetDict, maxWordLength, maxPredictions)),
mGestureDecoder(new GestureDecoderWrapper(maxWordLength, maxWords)) {
if (DEBUG_DICT) {
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index a1358890d..120ca5f7f 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -41,8 +41,8 @@ class Dictionary {
const static int KIND_SHORTCUT = 7; // A shortcut
const static int KIND_PREDICTION = 8; // A prediction (== a suggestion with no input)
- Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int typedLetterMultipler,
- int fullWordMultiplier, int maxWordLength, int maxWords, int maxPredictions);
+ Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust, int fullWordMultiplier,
+ int maxWordLength, int maxWords, int maxPredictions);
int getSuggestions(ProximityInfo *proximityInfo, void *traverseSession, int *xcoordinates,
int *ycoordinates, int *times, int *pointerIds, int *codes, int codesSize,
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index 392ec8194..015174356 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -518,7 +518,7 @@ float ProximityInfoState::getPointToKeyLength(const int inputIndex, const int co
}
int ProximityInfoState::getSpaceY() const {
- const int keyId = mProximityInfo->getKeyIndexOf(' ');
+ const int keyId = mProximityInfo->getKeyIndexOf(KEYCODE_SPACE);
return mProximityInfo->getKeyCenterYOfKeyIdG(keyId);
}
diff --git a/native/jni/src/unigram_dictionary.cpp b/native/jni/src/unigram_dictionary.cpp
index 49d044fbc..3b485a055 100644
--- a/native/jni/src/unigram_dictionary.cpp
+++ b/native/jni/src/unigram_dictionary.cpp
@@ -41,14 +41,12 @@ const UnigramDictionary::digraph_t UnigramDictionary::FRENCH_LIGATURES_DIGRAPHS[
{ 'o', 'e', 0x0153 } }; // U+0153 : LATIN SMALL LIGATURE OE
// TODO: check the header
-UnigramDictionary::UnigramDictionary(const uint8_t *const streamStart, int typedLetterMultiplier,
- int fullWordMultiplier, int maxWordLength, int maxWords, const unsigned int flags)
- : DICT_ROOT(streamStart), MAX_WORD_LENGTH(maxWordLength), MAX_WORDS(maxWords),
- TYPED_LETTER_MULTIPLIER(typedLetterMultiplier), FULL_WORD_MULTIPLIER(fullWordMultiplier),
- // TODO : remove this variable.
- ROOT_POS(0),
- BYTES_IN_ONE_CHAR(sizeof(int)),
- MAX_DIGRAPH_SEARCH_DEPTH(DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH), FLAGS(flags) {
+UnigramDictionary::UnigramDictionary(const uint8_t *const streamStart, int fullWordMultiplier,
+ int maxWordLength, int maxWords, const unsigned int flags)
+ : DICT_ROOT(streamStart), MAX_WORD_LENGTH(maxWordLength), MAX_WORDS(maxWords),
+ FULL_WORD_MULTIPLIER(fullWordMultiplier), // TODO : remove this variable.
+ ROOT_POS(0), BYTES_IN_ONE_CHAR(sizeof(int)),
+ MAX_DIGRAPH_SEARCH_DEPTH(DEFAULT_MAX_DIGRAPH_SEARCH_DEPTH), FLAGS(flags) {
if (DEBUG_DICT) {
AKLOGI("UnigramDictionary - constructor");
}
@@ -188,8 +186,7 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, const int *x
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer,
xCoordinatesBuffer, yCoordinatesBuffer, codesSize, bigramMap, bigramFilter,
useFullEditDistance, codes, codesSize, 0, codesBuffer, &masterCorrection,
- &queuePool, GERMAN_UMLAUT_DIGRAPHS,
- sizeof(GERMAN_UMLAUT_DIGRAPHS) / sizeof(GERMAN_UMLAUT_DIGRAPHS[0]));
+ &queuePool, GERMAN_UMLAUT_DIGRAPHS, NELEMS(GERMAN_UMLAUT_DIGRAPHS));
} else if (BinaryFormat::REQUIRES_FRENCH_LIGATURES_PROCESSING & FLAGS) {
int codesBuffer[getCodesBufferSize(codes, codesSize)];
int xCoordinatesBuffer[codesSize];
@@ -197,8 +194,7 @@ int UnigramDictionary::getSuggestions(ProximityInfo *proximityInfo, const int *x
getWordWithDigraphSuggestionsRec(proximityInfo, xcoordinates, ycoordinates, codesBuffer,
xCoordinatesBuffer, yCoordinatesBuffer, codesSize, bigramMap, bigramFilter,
useFullEditDistance, codes, codesSize, 0, codesBuffer, &masterCorrection,
- &queuePool, FRENCH_LIGATURES_DIGRAPHS,
- sizeof(FRENCH_LIGATURES_DIGRAPHS) / sizeof(FRENCH_LIGATURES_DIGRAPHS[0]));
+ &queuePool, FRENCH_LIGATURES_DIGRAPHS, NELEMS(FRENCH_LIGATURES_DIGRAPHS));
} else { // Normal processing
getWordSuggestions(proximityInfo, xcoordinates, ycoordinates, codes, codesSize,
bigramMap, bigramFilter, useFullEditDistance, &masterCorrection, &queuePool);
@@ -314,8 +310,6 @@ void UnigramDictionary::initSuggestions(ProximityInfo *proximityInfo, const int
correction->initCorrection(proximityInfo, inputSize, maxDepth);
}
-static const char SPACE = ' ';
-
void UnigramDictionary::getOneWordSuggestions(ProximityInfo *proximityInfo,
const int *xcoordinates, const int *ycoordinates, const int *codes,
const std::map *bigramMap, const uint8_t *bigramFilter,
@@ -570,7 +564,7 @@ int UnigramDictionary::getSubStringSuggestion(
if (outputWordStartPos + nextWordLength >= MAX_WORD_LENGTH) {
return FLAG_MULTIPLE_SUGGEST_SKIP;
}
- outputWord[tempOutputWordLength] = SPACE;
+ outputWord[tempOutputWordLength] = KEYCODE_SPACE;
if (outputWordLength) {
++*outputWordLength;
}
diff --git a/native/jni/src/unigram_dictionary.h b/native/jni/src/unigram_dictionary.h
index 57129bb07..244d78d8c 100644
--- a/native/jni/src/unigram_dictionary.h
+++ b/native/jni/src/unigram_dictionary.h
@@ -39,8 +39,8 @@ class UnigramDictionary {
static const int FLAG_MULTIPLE_SUGGEST_ABORT = 0;
static const int FLAG_MULTIPLE_SUGGEST_SKIP = 1;
static const int FLAG_MULTIPLE_SUGGEST_CONTINUE = 2;
- UnigramDictionary(const uint8_t *const streamStart, int typedLetterMultipler,
- int fullWordMultiplier, int maxWordLength, int maxWords, const unsigned int flags);
+ UnigramDictionary(const uint8_t *const streamStart, int fullWordMultiplier, int maxWordLength,
+ int maxWords, const unsigned int flags);
int getFrequency(const int32_t *const inWord, const int length) const;
int getBigramPosition(int pos, unsigned short *word, int offset, int length) const;
int getSuggestions(ProximityInfo *proximityInfo, const int *xcoordinates,
@@ -115,7 +115,6 @@ class UnigramDictionary {
const uint8_t *const DICT_ROOT;
const int MAX_WORD_LENGTH;
const int MAX_WORDS;
- const int TYPED_LETTER_MULTIPLIER;
const int FULL_WORD_MULTIPLIER;
const int ROOT_POS;
const unsigned int BYTES_IN_ONE_CHAR;
--
cgit v1.2.3-83-g751a
From 99b84b42f9517cbf7856aec93a6d5de30daaa325 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Tue, 9 Oct 2012 19:15:06 +0900
Subject: Use a freq of 1 instead of 0 for non-word shortcuts.
Also fix a spelling mistake in a comment
Bug: 7301525
Change-Id: I4437403dce620fed03871485ee04f13c51ce34fc
---
java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java | 2 +-
.../src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index fa9f79ecd..201a10187 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -350,7 +350,7 @@ final class BinaryDictionaryGetter {
// of the dictionary would lose whitelist functionality.
private static boolean hackCanUseDictionaryFile(final Locale locale, final File f) {
// Only for English - other languages didn't have a whitelist, hence this
- // ad-hock ## HACK ##
+ // ad-hoc ## HACK ##
if (!Locale.ENGLISH.getLanguage().equals(locale.getLanguage())) return true;
FileInputStream inStream = null;
diff --git a/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java b/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
index c31cd724a..252c3d655 100644
--- a/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
+++ b/tools/dicttool/src/android/inputmethod/latin/dicttool/XmlDictInputOutput.java
@@ -93,7 +93,7 @@ public class XmlDictInputOutput {
final FusionDictionary dict = mDictionary;
for (final String shortcutOnly : mShortcutsMap.keySet()) {
if (dict.hasWord(shortcutOnly)) continue;
- dict.add(shortcutOnly, 0, mShortcutsMap.get(shortcutOnly), true /* isNotAWord */);
+ dict.add(shortcutOnly, 1, mShortcutsMap.get(shortcutOnly), true /* isNotAWord */);
}
mDictionary = null;
mShortcutsMap.clear();
--
cgit v1.2.3-83-g751a
From 66c90cd2ae49c49da8aeda5ab1d86bd9b76434c7 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Thu, 11 Oct 2012 16:08:25 +0900
Subject: Put temporary files under a separate directory.
Bug: 7328003
Change-Id: Ibe5278ea209d149f87fd08785c77b17e3859948e
---
.../inputmethod/latin/BinaryDictionaryFileDumper.java | 5 +++--
.../android/inputmethod/latin/BinaryDictionaryGetter.java | 12 ++++++++++++
2 files changed, 15 insertions(+), 2 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index 46b363c10..b0b65edb6 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -46,7 +46,7 @@ public final class BinaryDictionaryFileDumper {
/**
* The size of the temporary buffer to copy files.
*/
- private static final int FILE_READ_BUFFER_SIZE = 1024;
+ private static final int FILE_READ_BUFFER_SIZE = 8192;
// TODO: make the following data common with the native code
private static final byte[] MAGIC_NUMBER_VERSION_1 =
new byte[] { (byte)0x78, (byte)0xB1, (byte)0x00, (byte)0x00 };
@@ -149,7 +149,7 @@ public final class BinaryDictionaryFileDumper {
final Uri.Builder wordListUriBuilder = getProviderUriBuilder(id);
final String finalFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
- final String tempFileName = finalFileName + ".tmp";
+ final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
InputStream originalSourceStream = null;
@@ -287,6 +287,7 @@ public final class BinaryDictionaryFileDumper {
* @param input the stream to be copied.
* @param output an output stream to copy the data to.
*/
+ // TODO: make output a BufferedOutputStream
private static void checkMagicAndCopyFileTo(final BufferedInputStream input,
final FileOutputStream output) throws FileNotFoundException, IOException {
// Check the magic number
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 201a10187..c747dc673 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -163,6 +163,18 @@ final class BinaryDictionaryGetter {
return getCacheDirectoryForLocale(locale, context) + File.separator + fileName;
}
+ /**
+ * Generates a unique temporary file name in the app cache directory.
+ *
+ * This is unique as long as it doesn't get called twice in the same millisecond by the same
+ * thread, which should be more than enough for our purposes.
+ */
+ public static String getTempFileName(String id, Context context) {
+ final String fileName = replaceFileNameDangerousCharacters(id);
+ return context.getCacheDir() + File.separator + fileName + "."
+ + Thread.currentThread().getId() + "." + System.currentTimeMillis();
+ }
+
/**
* Returns a file address from a resource, or null if it cannot be opened.
*/
--
cgit v1.2.3-83-g751a
From 01e0913ad20b24cc2b7b4dc2f4cbac03ccd4bc0e Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Fri, 12 Oct 2012 18:07:30 +0900
Subject: Make a better choice for the temporary file
Change-Id: I745bb285b6b52875c8d2b3a94deb962352f9754e
---
.../android/inputmethod/latin/BinaryDictionaryFileDumper.java | 8 +++++++-
.../com/android/inputmethod/latin/BinaryDictionaryGetter.java | 9 ++-------
2 files changed, 9 insertions(+), 8 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index b0b65edb6..bed31a7d1 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -149,7 +149,13 @@ public final class BinaryDictionaryFileDumper {
final Uri.Builder wordListUriBuilder = getProviderUriBuilder(id);
final String finalFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
- final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
+ String tempFileName;
+ try {
+ tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
+ } catch (IOException e) {
+ Log.e(TAG, "Can't open the temporary file", e);
+ return null;
+ }
for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
InputStream originalSourceStream = null;
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index c747dc673..ecb61b46f 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -165,14 +165,9 @@ final class BinaryDictionaryGetter {
/**
* Generates a unique temporary file name in the app cache directory.
- *
- * This is unique as long as it doesn't get called twice in the same millisecond by the same
- * thread, which should be more than enough for our purposes.
*/
- public static String getTempFileName(String id, Context context) {
- final String fileName = replaceFileNameDangerousCharacters(id);
- return context.getCacheDir() + File.separator + fileName + "."
- + Thread.currentThread().getId() + "." + System.currentTimeMillis();
+ public static String getTempFileName(String id, Context context) throws IOException {
+ return File.createTempFile(replaceFileNameDangerousCharacters(id), null).getAbsolutePath();
}
/**
--
cgit v1.2.3-83-g751a
From 6686e63f2158eff07e39ff002ba211d0578f2a4f Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Wed, 17 Oct 2012 05:21:52 +0900
Subject: Honor automatic shift turned off for gestures
Bug: 7354129
Change-Id: Ia02336e8cea2f04b629edbe74b7815cce0d7fad6
---
java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java | 4 +++-
java/src/com/android/inputmethod/latin/LatinIME.java | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index e99e956e2..38025e8e4 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -389,7 +389,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
}
- public int getManualCapsMode() {
+ public int getKeyboardShiftMode() {
final Keyboard keyboard = getKeyboard();
if (keyboard == null) {
return WordComposer.CAPS_MODE_OFF;
@@ -400,6 +400,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
return WordComposer.CAPS_MODE_MANUAL_SHIFT_LOCKED;
case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
return WordComposer.CAPS_MODE_MANUAL_SHIFTED;
+ case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
+ return WordComposer.CAPS_MODE_AUTO_SHIFTED;
default:
return WordComposer.CAPS_MODE_OFF;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d98966e96..cd20ba3a3 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1119,8 +1119,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Factor in auto-caps and manual caps and compute the current caps mode.
private int getActualCapsMode() {
- final int manual = mKeyboardSwitcher.getManualCapsMode();
- if (manual != WordComposer.CAPS_MODE_OFF) return manual;
+ final int keyboardShiftMode = mKeyboardSwitcher.getKeyboardShiftMode();
+ if (keyboardShiftMode != WordComposer.CAPS_MODE_AUTO_SHIFTED) return keyboardShiftMode;
final int auto = getCurrentAutoCapsState();
if (0 != (auto & TextUtils.CAP_MODE_CHARACTERS)) {
return WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED;
--
cgit v1.2.3-83-g751a
From bdc8b9e42b90e1fdf8e15d7ee5c0d319934fec0a Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Tue, 16 Oct 2012 13:26:45 -0700
Subject: Fix more suggestions text width calculation
Bug: 7345983
Change-Id: Ic1554db98e7aaf032eb90a98c0c37c7c789461b5
---
java/src/com/android/inputmethod/keyboard/KeyboardView.java | 3 ++-
.../com/android/inputmethod/latin/suggestions/MoreSuggestions.java | 4 +++-
.../android/inputmethod/latin/suggestions/MoreSuggestionsView.java | 4 ++++
3 files changed, 9 insertions(+), 2 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index b39f2bad3..472f74b12 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -105,7 +105,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private static final String TAG = KeyboardView.class.getSimpleName();
// XML attributes
- private final KeyVisualAttributes mKeyVisualAttributes;
+ protected final KeyVisualAttributes mKeyVisualAttributes;
private final int mKeyLabelHorizontalPadding;
private final float mKeyHintLetterPadding;
private final float mKeyPopupHintLetterPadding;
@@ -733,6 +733,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
return width;
}
+ // TODO: Remove this method.
public float getLabelWidth(final String label, final Paint paint) {
paint.getTextBounds(label, 0, label.length(), mTextBounds);
return mTextBounds.width();
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index e9bf0fac4..4e9fd1968 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -51,10 +51,11 @@ public final class MoreSuggestions extends Keyboard {
super();
}
+ // TODO: Remove {@link MoreSuggestionsView} argument.
public int layout(final SuggestedWords suggestions, final int fromPos, final int maxWidth,
final int minWidth, final int maxRow, final MoreSuggestionsView view) {
clearKeys();
- final Resources res = view.getContext().getResources();
+ final Resources res = view.getResources();
mDivider = res.getDrawable(R.drawable.more_suggestions_divider);
mDividerWidth = mDivider.getIntrinsicWidth();
final int padding = (int) res.getDimension(
@@ -181,6 +182,7 @@ public final class MoreSuggestions extends Keyboard {
load(xmlId, keyboard.mId);
mParams.mVerticalGap = mParams.mTopPadding = keyboard.mVerticalGap / 2;
+ mPaneView.updateKeyboardGeometry(mParams.mDefaultRowHeight);
final int count = mParams.layout(suggestions, fromPos, maxWidth, minWidth, maxRow,
mPaneView);
mFromPos = fromPos;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index 9b9a35478..03a2e73d1 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -105,6 +105,10 @@ public final class MoreSuggestionsView extends KeyboardView implements MoreKeysP
}
}
+ public void updateKeyboardGeometry(final int keyHeight) {
+ mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes);
+ }
+
@Override
public void setKeyboard(Keyboard keyboard) {
super.setKeyboard(keyboard);
--
cgit v1.2.3-83-g751a
From e91d495c53a2606962159cfddada2b7a5e206c4c Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Wed, 17 Oct 2012 06:41:15 +0900
Subject: Have "no whitespace before cursor" upon gesture trigger phantom space
Bug: 7359291
Bug: 7357758
Bug: 7197651
Change-Id: Ia805a87e922739ae0a06978a3bf00d91c94b6c51
---
java/src/com/android/inputmethod/latin/LatinIME.java | 8 ++++++++
java/src/com/android/inputmethod/latin/RichInputConnection.java | 7 +++++++
2 files changed, 15 insertions(+)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index d98966e96..c1c5112a1 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1429,6 +1429,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// The following is necessary for the case where the user typed something but didn't
// manual pick it and didn't input any separator.
mSpaceState = SPACE_STATE_PHANTOM;
+ } else {
+ final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor();
+ if (Constants.NOT_A_CODE != codePointBeforeCursor
+ && !Character.isWhitespace(codePointBeforeCursor)) {
+ mSpaceState = SPACE_STATE_PHANTOM;
+ }
}
mConnection.endBatchEdit();
mWordComposer.setCapitalizedModeAtStartComposingTime(getActualCapsMode());
@@ -1564,6 +1570,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// We have a TLD (or something that looks like this): make sure we don't add
// a space even if currently in phantom mode.
mSpaceState = SPACE_STATE_NONE;
+ // TODO: use getCodePointBeforeCursor instead to improve performance and simplify the code
final CharSequence lastOne = mConnection.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == Keyboard.CODE_PERIOD) {
@@ -2284,6 +2291,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// This is a stopgap solution to avoid leaving a high surrogate alone in a text view.
// In the future, we need to deprecate deteleSurroundingText() and have a surrogate
// pair-friendly way of deleting characters in InputConnection.
+ // TODO: use getCodePointBeforeCursor instead to improve performance
final CharSequence lastChar = mConnection.getTextBeforeCursor(1, 0);
if (!TextUtils.isEmpty(lastChar) && Character.isHighSurrogate(lastChar.charAt(0))) {
mConnection.deleteSurroundingText(1, 0);
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index b27db579f..21441369e 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -235,7 +235,14 @@ public final class RichInputConnection {
hasSpaceBefore);
}
+ public int getCodePointBeforeCursor() {
+ if (mCommittedTextBeforeComposingText.length() < 1) return Constants.NOT_A_CODE;
+ return Character.codePointBefore(mCommittedTextBeforeComposingText,
+ mCommittedTextBeforeComposingText.length());
+ }
+
public CharSequence getTextBeforeCursor(final int i, final int j) {
+ // TODO: use mCommittedTextBeforeComposingText if possible to improve performance
mIC = mParent.getCurrentInputConnection();
if (null != mIC) return mIC.getTextBeforeCursor(i, j);
return null;
--
cgit v1.2.3-83-g751a
From 8e360c68f1861a70fdb91652334efa513e25fcd2 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Mon, 15 Oct 2012 13:59:35 -0700
Subject: Move AudioAndHapticFeedbackManager from LatinIME to KeyboardSwitcher
Bug: 7313372
Change-Id: I9bd3275f57ed3f5c2c4a95768443af505513ee97
---
.../inputmethod/keyboard/KeyboardSwitcher.java | 12 ++++++++++--
.../latin/AudioAndHapticFeedbackManager.java | 22 ++++++++++++----------
.../com/android/inputmethod/latin/LatinIME.java | 12 +-----------
3 files changed, 23 insertions(+), 23 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 38025e8e4..7e0ea1699 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -29,6 +29,7 @@ import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.keyboard.internal.KeyboardState;
+import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
import com.android.inputmethod.latin.DebugSettings;
import com.android.inputmethod.latin.ImfUtils;
import com.android.inputmethod.latin.InputView;
@@ -65,6 +66,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
new KeyboardTheme(5, R.style.KeyboardTheme_IceCreamSandwich),
};
+ private AudioAndHapticFeedbackManager mFeedbackManager;
private SubtypeSwitcher mSubtypeSwitcher;
private SharedPreferences mPrefs;
private boolean mForceNonDistinctMultitouch;
@@ -102,6 +104,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private void initInternal(LatinIME latinIme, SharedPreferences prefs) {
mLatinIME = latinIme;
mResources = latinIme.getResources();
+ mFeedbackManager = new AudioAndHapticFeedbackManager(latinIme);
mPrefs = prefs;
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mState = new KeyboardState(this);
@@ -147,6 +150,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mKeyboardLayoutSet = builder.build();
try {
mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols));
+ mFeedbackManager.onSettingsChanged(settingsValues);
} catch (KeyboardLayoutSetException e) {
Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
LatinImeLogger.logOnException(e.mKeyboardId.toString(), e.getCause());
@@ -154,6 +158,10 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
}
+ public void onRingerModeChanged() {
+ mFeedbackManager.onRingerModeChanged();
+ }
+
public void saveKeyboardState() {
if (getKeyboard() != null) {
mState.onSaveKeyboardState();
@@ -202,7 +210,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
public void onPressKey(int code) {
if (isVibrateAndSoundFeedbackRequired()) {
- mLatinIME.hapticAndAudioFeedback(code);
+ mFeedbackManager.hapticAndAudioFeedback(code, mKeyboardView);
}
mState.onPressKey(code, isSinglePointer(), mLatinIME.getCurrentAutoCapsState());
}
@@ -314,7 +322,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void hapticAndAudioFeedback(int code) {
- mLatinIME.hapticAndAudioFeedback(code);
+ mFeedbackManager.hapticAndAudioFeedback(code, mKeyboardView);
}
public void onLongPressTimeout(int code) {
diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
index 59ef5e09f..91bbd54c7 100644
--- a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
+++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
@@ -31,17 +31,15 @@ import com.android.inputmethod.latin.VibratorUtils;
* complexity of settings and the like.
*/
public final class AudioAndHapticFeedbackManager {
- final private SettingsValues mSettingsValues;
- final private AudioManager mAudioManager;
- final private VibratorUtils mVibratorUtils;
+ private final AudioManager mAudioManager;
+ private final VibratorUtils mVibratorUtils;
+
+ private SettingsValues mSettingsValues;
private boolean mSoundOn;
- public AudioAndHapticFeedbackManager(final LatinIME latinIme,
- final SettingsValues settingsValues) {
- mSettingsValues = settingsValues;
+ public AudioAndHapticFeedbackManager(final LatinIME latinIme) {
mVibratorUtils = VibratorUtils.getInstance(latinIme);
mAudioManager = (AudioManager) latinIme.getSystemService(Context.AUDIO_SERVICE);
- mSoundOn = reevaluateIfSoundIsOn();
}
public void hapticAndAudioFeedback(final int primaryCode,
@@ -51,7 +49,7 @@ public final class AudioAndHapticFeedbackManager {
}
private boolean reevaluateIfSoundIsOn() {
- if (!mSettingsValues.mSoundOn || mAudioManager == null) {
+ if (mSettingsValues == null || !mSettingsValues.mSoundOn || mAudioManager == null) {
return false;
} else {
return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
@@ -81,8 +79,7 @@ public final class AudioAndHapticFeedbackManager {
}
}
- // TODO: make this private when LatinIME does not call it any more
- public void vibrate(final View viewToPerformHapticFeedbackOn) {
+ private void vibrate(final View viewToPerformHapticFeedbackOn) {
if (!mSettingsValues.mVibrateOn) {
return;
}
@@ -98,6 +95,11 @@ public final class AudioAndHapticFeedbackManager {
}
}
+ public void onSettingsChanged(final SettingsValues settingsValues) {
+ mSettingsValues = settingsValues;
+ mSoundOn = reevaluateIfSoundIsOn();
+ }
+
public void onRingerModeChanged() {
mSoundOn = reevaluateIfSoundIsOn();
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 044d6de18..4cf6a5112 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -163,8 +163,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private int mDeleteCount;
private long mLastKeyTime;
- private AudioAndHapticFeedbackManager mFeedbackManager;
-
// Member variables for remembering the current device orientation.
private int mDisplayOrientation;
@@ -438,7 +436,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
};
mCurrentSettings = job.runInLocale(mResources, mSubtypeSwitcher.getCurrentSubtypeLocale());
- mFeedbackManager = new AudioAndHapticFeedbackManager(this, mCurrentSettings);
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
}
@@ -2251,13 +2248,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mHandler.postUpdateSuggestionStrip();
}
- // TODO: Remove this method from {@link LatinIME} and move {@link FeedbackManager} to
- // {@link KeyboardSwitcher}. Called from KeyboardSwitcher
- public void hapticAndAudioFeedback(final int primaryCode) {
- mFeedbackManager.hapticAndAudioFeedback(
- primaryCode, mKeyboardSwitcher.getMainKeyboardView());
- }
-
// Callback called by PointerTracker through the KeyboardActionListener. This is called when a
// key is depressed; release matching call is onReleaseKey below.
@Override
@@ -2303,7 +2293,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
mSubtypeSwitcher.onNetworkStateChanged(intent);
} else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
- mFeedbackManager.onRingerModeChanged();
+ mKeyboardSwitcher.onRingerModeChanged();
}
}
};
--
cgit v1.2.3-83-g751a
From 5faf41951929301af80026bc3191812ef874fd5a Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Mon, 15 Oct 2012 13:59:35 -0700
Subject: Suggestion strip will honor haptic feedback settings of keyboard
Bug: 7313372
Change-Id: I427da8de68be3d2a78e810556340b96ab4edcc2d
---
java/res/layout/suggestion_word.xml | 3 +++
.../com/android/inputmethod/latin/suggestions/SuggestionStripView.java | 2 ++
2 files changed, 5 insertions(+)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/res/layout/suggestion_word.xml b/java/res/layout/suggestion_word.xml
index d64cacf04..fa00e041e 100644
--- a/java/res/layout/suggestion_word.xml
+++ b/java/res/layout/suggestion_word.xml
@@ -18,6 +18,8 @@
*/
-->
+
Date: Wed, 3 Oct 2012 15:19:43 +0900
Subject: Replace useless CharSequence to String
Change-Id: Idc478f901185ee1b4912acc82d0cbc54fee4e991
---
.../inputmethod/compat/SuggestionSpanUtils.java | 19 ++--
.../keyboard/KeyboardActionListener.java | 10 +-
.../inputmethod/keyboard/MoreKeysKeyboardView.java | 32 ++++---
.../android/inputmethod/latin/AutoCorrection.java | 23 +++--
.../inputmethod/latin/BinaryDictionary.java | 28 +++---
.../latin/ContactsBinaryDictionary.java | 15 +--
.../com/android/inputmethod/latin/Dictionary.java | 10 +-
.../inputmethod/latin/DictionaryCollection.java | 6 +-
.../latin/ExpandableBinaryDictionary.java | 14 +--
.../inputmethod/latin/ExpandableDictionary.java | 50 +++++-----
.../inputmethod/latin/LastComposedWord.java | 4 +-
.../com/android/inputmethod/latin/LatinIME.java | 54 ++++++-----
.../inputmethod/latin/RichInputConnection.java | 30 +++---
.../com/android/inputmethod/latin/StringUtils.java | 104 +++++----------------
.../src/com/android/inputmethod/latin/Suggest.java | 39 ++++----
.../android/inputmethod/latin/SuggestedWords.java | 25 ++---
...ynchronouslyLoadedContactsBinaryDictionary.java | 4 +-
.../SynchronouslyLoadedUserBinaryDictionary.java | 4 +-
.../inputmethod/latin/UserBinaryDictionary.java | 2 +-
.../inputmethod/latin/UserHistoryDictionary.java | 24 ++---
.../android/inputmethod/latin/WordComposer.java | 19 ++--
.../spellcheck/AndroidSpellCheckerService.java | 4 +-
.../AndroidWordLevelSpellCheckerSession.java | 2 +-
.../latin/spellcheck/DictionaryPool.java | 4 +-
.../latin/suggestions/MoreSuggestions.java | 2 +-
.../latin/suggestions/SuggestionStripView.java | 18 ++--
.../android/inputmethod/latin/InputTestsBase.java | 2 +-
27 files changed, 249 insertions(+), 299 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index 9a89eedd0..c1609ea28 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -83,14 +83,13 @@ public final class SuggestionSpanUtils {
}
public static CharSequence getTextWithAutoCorrectionIndicatorUnderline(
- Context context, CharSequence text) {
+ final Context context, final String text) {
if (TextUtils.isEmpty(text) || CONSTRUCTOR_SuggestionSpan == null
|| OBJ_FLAG_AUTO_CORRECTION == null || OBJ_SUGGESTIONS_MAX_SIZE == null
|| OBJ_FLAG_MISSPELLED == null || OBJ_FLAG_EASY_CORRECT == null) {
return text;
}
- final Spannable spannable = text instanceof Spannable
- ? (Spannable) text : new SpannableString(text);
+ final Spannable spannable = new SpannableString(text);
final Object[] args =
{ context, null, new String[] {}, (int)OBJ_FLAG_AUTO_CORRECTION,
(Class>) SuggestionSpanPickedNotificationReceiver.class };
@@ -104,8 +103,9 @@ public final class SuggestionSpanUtils {
return spannable;
}
- public static CharSequence getTextWithSuggestionSpan(Context context,
- CharSequence pickedWord, SuggestedWords suggestedWords, boolean dictionaryAvailable) {
+ public static CharSequence getTextWithSuggestionSpan(final Context context,
+ final String pickedWord, final SuggestedWords suggestedWords,
+ final boolean dictionaryAvailable) {
if (!dictionaryAvailable || TextUtils.isEmpty(pickedWord)
|| CONSTRUCTOR_SuggestionSpan == null
|| suggestedWords.isEmpty() || suggestedWords.mIsPrediction
@@ -114,18 +114,13 @@ public final class SuggestionSpanUtils {
return pickedWord;
}
- final Spannable spannable;
- if (pickedWord instanceof Spannable) {
- spannable = (Spannable) pickedWord;
- } else {
- spannable = new SpannableString(pickedWord);
- }
+ final Spannable spannable = new SpannableString(pickedWord);
final ArrayList suggestionsList = CollectionUtils.newArrayList();
for (int i = 0; i < suggestedWords.size(); ++i) {
if (suggestionsList.size() >= OBJ_SUGGESTIONS_MAX_SIZE) {
break;
}
- final CharSequence word = suggestedWords.getWord(i);
+ final String word = suggestedWords.getWord(i);
if (!TextUtils.equals(pickedWord, word)) {
suggestionsList.add(word.toString());
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
index 5c8f78f5e..e7a4e82a2 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java
@@ -56,11 +56,11 @@ public interface KeyboardActionListener {
public void onCodeInput(int primaryCode, int x, int y);
/**
- * Sends a sequence of characters to the listener.
+ * Sends a string of characters to the listener.
*
- * @param text the sequence of characters to be displayed.
+ * @param text the string of characters to be registered.
*/
- public void onTextInput(CharSequence text);
+ public void onTextInput(String text);
/**
* Called when user started batch input.
@@ -99,7 +99,7 @@ public interface KeyboardActionListener {
@Override
public void onCodeInput(int primaryCode, int x, int y) {}
@Override
- public void onTextInput(CharSequence text) {}
+ public void onTextInput(String text) {}
@Override
public void onStartBatchInput() {}
@Override
@@ -114,7 +114,7 @@ public interface KeyboardActionListener {
}
// TODO: Remove this method when the vertical correction is removed.
- public static boolean isInvalidCoordinate(int coordinate) {
+ public static boolean isInvalidCoordinate(final int coordinate) {
// Detect {@link Constants#NOT_A_COORDINATE},
// {@link Constants#SUGGESTION_STRIP_COORDINATE}, and
// {@link Constants#SPELL_CHECKER_COORDINATE}.
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index a50617693..9c450e994 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -48,7 +48,7 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
private final KeyboardActionListener mMoreKeysKeyboardListener =
new KeyboardActionListener.Adapter() {
@Override
- public void onCodeInput(int primaryCode, int x, int y) {
+ public void onCodeInput(final int primaryCode, final int x, final int y) {
// Because a more keys keyboard doesn't need proximity characters correction, we don't
// send touch event coordinates.
mListener.onCodeInput(
@@ -56,7 +56,7 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
}
@Override
- public void onTextInput(CharSequence text) {
+ public void onTextInput(final String text) {
mListener.onTextInput(text);
}
@@ -66,12 +66,12 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
}
@Override
- public void onUpdateBatchInput(InputPointers batchPointers) {
+ public void onUpdateBatchInput(final InputPointers batchPointers) {
mListener.onUpdateBatchInput(batchPointers);
}
@Override
- public void onEndBatchInput(InputPointers batchPointers) {
+ public void onEndBatchInput(final InputPointers batchPointers) {
mListener.onEndBatchInput(batchPointers);
}
@@ -81,21 +81,22 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
}
@Override
- public void onPressKey(int primaryCode) {
+ public void onPressKey(final int primaryCode) {
mListener.onPressKey(primaryCode);
}
@Override
- public void onReleaseKey(int primaryCode, boolean withSliding) {
+ public void onReleaseKey(final int primaryCode, final boolean withSliding) {
mListener.onReleaseKey(primaryCode, withSliding);
}
};
- public MoreKeysKeyboardView(Context context, AttributeSet attrs) {
+ public MoreKeysKeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
}
- public MoreKeysKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+ public MoreKeysKeyboardView(final Context context, final AttributeSet attrs,
+ final int defStyle) {
super(context, attrs, defStyle);
final Resources res = context.getResources();
@@ -105,7 +106,7 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
}
@Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final Keyboard keyboard = getKeyboard();
if (keyboard != null) {
final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
@@ -117,7 +118,7 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
}
@Override
- public void setKeyboard(Keyboard keyboard) {
+ public void setKeyboard(final Keyboard keyboard) {
super.setKeyboard(keyboard);
mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
-getPaddingTop() + mVerticalCorrection);
@@ -144,15 +145,16 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
}
@Override
- public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+ public void setKeyPreviewPopupEnabled(final boolean previewEnabled, final int delay) {
// More keys keyboard needs no pop-up key preview displayed, so we pass always false with a
// delay of 0. The delay does not matter actually since the popup is not shown anyway.
super.setKeyPreviewPopupEnabled(false, 0);
}
@Override
- public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
- PopupWindow window, KeyboardActionListener listener) {
+ public void showMoreKeysPanel(final View parentView, final Controller controller,
+ final int pointX, final int pointY, final PopupWindow window,
+ final KeyboardActionListener listener) {
mController = controller;
mListener = listener;
final View container = (View)getParent();
@@ -185,12 +187,12 @@ public final class MoreKeysKeyboardView extends KeyboardView implements MoreKeys
}
@Override
- public int translateX(int x) {
+ public int translateX(final int x) {
return x - mOriginX;
}
@Override
- public int translateY(int y) {
+ public int translateY(final int y) {
return y - mOriginY;
}
}
diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java
index 84fad158f..fa35922b0 100644
--- a/java/src/com/android/inputmethod/latin/AutoCorrection.java
+++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java
@@ -33,11 +33,11 @@ public final class AutoCorrection {
}
public static boolean isValidWord(final ConcurrentHashMap dictionaries,
- CharSequence word, boolean ignoreCase) {
+ final String word, final boolean ignoreCase) {
if (TextUtils.isEmpty(word)) {
return false;
}
- final CharSequence lowerCasedWord = word.toString().toLowerCase();
+ final String lowerCasedWord = word.toLowerCase();
for (final String key : dictionaries.keySet()) {
final Dictionary dictionary = dictionaries.get(key);
// It's unclear how realistically 'dictionary' can be null, but the monkey is somehow
@@ -57,7 +57,7 @@ public final class AutoCorrection {
}
public static int getMaxFrequency(final ConcurrentHashMap dictionaries,
- CharSequence word) {
+ final String word) {
if (TextUtils.isEmpty(word)) {
return Dictionary.NOT_A_PROBABILITY;
}
@@ -76,12 +76,13 @@ public final class AutoCorrection {
// Returns true if this is in any of the dictionaries.
public static boolean isInTheDictionary(
final ConcurrentHashMap dictionaries,
- final CharSequence word, final boolean ignoreCase) {
+ final String word, final boolean ignoreCase) {
return isValidWord(dictionaries, word, ignoreCase);
}
- public static boolean suggestionExceedsAutoCorrectionThreshold(SuggestedWordInfo suggestion,
- CharSequence consideredWord, float autoCorrectionThreshold) {
+ public static boolean suggestionExceedsAutoCorrectionThreshold(
+ final SuggestedWordInfo suggestion, final String consideredWord,
+ final float autoCorrectionThreshold) {
if (null != suggestion) {
// Shortlist a whitelisted word
if (suggestion.mKind == SuggestedWordInfo.KIND_WHITELIST) return true;
@@ -89,8 +90,7 @@ public final class AutoCorrection {
// TODO: when the normalized score of the first suggestion is nearly equals to
// the normalized score of the second suggestion, behave less aggressive.
final float normalizedScore = BinaryDictionary.calcNormalizedScore(
- consideredWord.toString(), suggestion.mWord.toString(),
- autoCorrectionSuggestionScore);
+ consideredWord, suggestion.mWord, autoCorrectionSuggestionScore);
if (DBG) {
Log.d(TAG, "Normalized " + consideredWord + "," + suggestion + ","
+ autoCorrectionSuggestionScore + ", " + normalizedScore
@@ -100,8 +100,7 @@ public final class AutoCorrection {
if (DBG) {
Log.d(TAG, "Auto corrected by S-threshold.");
}
- return !shouldBlockAutoCorrectionBySafetyNet(consideredWord.toString(),
- suggestion.mWord);
+ return !shouldBlockAutoCorrectionBySafetyNet(consideredWord, suggestion.mWord);
}
}
return false;
@@ -110,7 +109,7 @@ public final class AutoCorrection {
// TODO: Resolve the inconsistencies between the native auto correction algorithms and
// this safety net
public static boolean shouldBlockAutoCorrectionBySafetyNet(final String typedWord,
- final CharSequence suggestion) {
+ final String suggestion) {
// Safety net for auto correction.
// Actually if we hit this safety net, it's a bug.
// If user selected aggressive auto correction mode, there is no need to use the safety
@@ -123,7 +122,7 @@ public final class AutoCorrection {
}
final int maxEditDistanceOfNativeDictionary =
(typedWordLength < 5 ? 2 : typedWordLength / 2) + 1;
- final int distance = BinaryDictionary.editDistance(typedWord, suggestion.toString());
+ final int distance = BinaryDictionary.editDistance(typedWord, suggestion);
if (DBG) {
Log.d(TAG, "Autocorrected edit distance = " + distance
+ ", " + maxEditDistanceOfNativeDictionary);
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 9c48aa1a4..e4275de19 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -64,7 +64,7 @@ public final class BinaryDictionary extends Dictionary {
// TODO: There should be a way to remove used DicTraverseSession objects from
// {@code mDicTraverseSessions}.
- private DicTraverseSession getTraverseSession(int traverseSessionId) {
+ private DicTraverseSession getTraverseSession(final int traverseSessionId) {
synchronized(mDicTraverseSessions) {
DicTraverseSession traverseSession = mDicTraverseSessions.get(traverseSessionId);
if (traverseSession == null) {
@@ -116,26 +116,27 @@ public final class BinaryDictionary extends Dictionary {
private static native int editDistanceNative(char[] before, char[] after);
// TODO: Move native dict into session
- private final void loadDictionary(String path, long startOffset, long length) {
+ private final void loadDictionary(final String path, final long startOffset,
+ final long length) {
mNativeDict = openNative(path, startOffset, length, FULL_WORD_SCORE_MULTIPLIER,
MAX_WORD_LENGTH, MAX_WORDS, MAX_PREDICTIONS);
}
@Override
public ArrayList getSuggestions(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo) {
+ final String prevWord, final ProximityInfo proximityInfo) {
return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, 0);
}
@Override
public ArrayList getSuggestionsWithSessionId(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo, int sessionId) {
+ final String prevWord, final ProximityInfo proximityInfo, int sessionId) {
if (!isValidDictionary()) return null;
Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE);
// TODO: toLowerCase in the native code
final int[] prevWordCodePointArray = (null == prevWord)
- ? null : StringUtils.toCodePointArray(prevWord.toString());
+ ? null : StringUtils.toCodePointArray(prevWord);
final int composerSize = composer.size();
final boolean isGesture = composer.isBatchMode();
@@ -178,11 +179,12 @@ public final class BinaryDictionary extends Dictionary {
return mNativeDict != 0;
}
- public static float calcNormalizedScore(String before, String after, int score) {
+ public static float calcNormalizedScore(final String before, final String after,
+ final int score) {
return calcNormalizedScoreNative(before.toCharArray(), after.toCharArray(), score);
}
- public static int editDistance(String before, String after) {
+ public static int editDistance(final String before, final String after) {
if (before == null || after == null) {
throw new IllegalArgumentException();
}
@@ -190,23 +192,23 @@ public final class BinaryDictionary extends Dictionary {
}
@Override
- public boolean isValidWord(CharSequence word) {
+ public boolean isValidWord(final String word) {
return getFrequency(word) >= 0;
}
@Override
- public int getFrequency(CharSequence word) {
+ public int getFrequency(final String word) {
if (word == null) return -1;
- int[] codePoints = StringUtils.toCodePointArray(word.toString());
+ int[] codePoints = StringUtils.toCodePointArray(word);
return getFrequencyNative(mNativeDict, codePoints);
}
// TODO: Add a batch process version (isValidBigramMultiple?) to avoid excessive numbers of jni
// calls when checking for changes in an entire dictionary.
- public boolean isValidBigram(CharSequence word1, CharSequence word2) {
+ public boolean isValidBigram(final String word1, final String word2) {
if (TextUtils.isEmpty(word1) || TextUtils.isEmpty(word2)) return false;
- int[] chars1 = StringUtils.toCodePointArray(word1.toString());
- int[] chars2 = StringUtils.toCodePointArray(word2.toString());
+ final int[] chars1 = StringUtils.toCodePointArray(word1);
+ final int[] chars2 = StringUtils.toCodePointArray(word2);
return isValidBigramNative(mNativeDict, chars1, chars2);
}
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 5edc4314f..7c0448024 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -62,7 +62,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
*/
private final boolean mUseFirstLastBigrams;
- public ContactsBinaryDictionary(final Context context, Locale locale) {
+ public ContactsBinaryDictionary(final Context context, final Locale locale) {
super(context, getFilenameWithLocale(NAME, locale.toString()), Dictionary.TYPE_CONTACTS);
mLocale = locale;
mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
@@ -120,7 +120,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
}
- private boolean useFirstLastBigramsForLocale(Locale locale) {
+ private boolean useFirstLastBigramsForLocale(final Locale locale) {
// TODO: Add firstname/lastname bigram rules for other languages.
if (locale != null && locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
return true;
@@ -128,7 +128,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return false;
}
- private void addWords(Cursor cursor) {
+ private void addWords(final Cursor cursor) {
clearFusionDictionary();
int count = 0;
while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) {
@@ -160,7 +160,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
* Adds the words in a name (e.g., firstname/lastname) to the binary dictionary along with their
* bigrams depending on locale.
*/
- private void addName(String name) {
+ private void addName(final String name) {
int len = StringUtils.codePointCount(name);
String prevWord = null;
// TODO: Better tokenization for non-Latin writing systems
@@ -188,7 +188,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
/**
* Returns the index of the last letter in the word, starting from position startIndex.
*/
- private static int getWordEndPosition(String string, int len, int startIndex) {
+ private static int getWordEndPosition(final String string, final int len,
+ final int startIndex) {
int end;
int cp = 0;
for (end = startIndex + 1; end < len; end += Character.charCount(cp)) {
@@ -249,7 +250,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return false;
}
- private static boolean isValidName(String name) {
+ private static boolean isValidName(final String name) {
if (name != null && -1 == name.indexOf('@')) {
return true;
}
@@ -259,7 +260,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
/**
* Checks if the words in a name are in the current binary dictionary.
*/
- private boolean isNameInDictionary(String name) {
+ private boolean isNameInDictionary(final String name) {
int len = StringUtils.codePointCount(name);
String prevWord = null;
for (int i = 0; i < len; i++) {
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 88d0c09dd..8207bc47f 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -59,12 +59,12 @@ public abstract class Dictionary {
// TODO: pass more context than just the previous word, to enable better suggestions (n-gram
// and more)
abstract public ArrayList getSuggestions(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo);
+ final String prevWord, final ProximityInfo proximityInfo);
// The default implementation of this method ignores sessionId.
// Subclasses that want to use sessionId need to override this method.
public ArrayList getSuggestionsWithSessionId(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo, int sessionId) {
+ final String prevWord, final ProximityInfo proximityInfo, final int sessionId) {
return getSuggestions(composer, prevWord, proximityInfo);
}
@@ -73,9 +73,9 @@ public abstract class Dictionary {
* @param word the word to search for. The search should be case-insensitive.
* @return true if the word exists, false otherwise
*/
- abstract public boolean isValidWord(CharSequence word);
+ abstract public boolean isValidWord(final String word);
- public int getFrequency(CharSequence word) {
+ public int getFrequency(final String word) {
return NOT_A_PROBABILITY;
}
@@ -87,7 +87,7 @@ public abstract class Dictionary {
* @param typedWord the word to compare with
* @return true if they are the same, false otherwise.
*/
- protected boolean same(final char[] word, final int length, final CharSequence typedWord) {
+ protected boolean same(final char[] word, final int length, final String typedWord) {
if (typedWord.length() != length) {
return false;
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index d3b120989..7f78ac8a2 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -56,7 +56,7 @@ public final class DictionaryCollection extends Dictionary {
@Override
public ArrayList getSuggestions(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo) {
+ final String prevWord, final ProximityInfo proximityInfo) {
final CopyOnWriteArrayList dictionaries = mDictionaries;
if (dictionaries.isEmpty()) return null;
// To avoid creating unnecessary objects, we get the list out of the first
@@ -74,14 +74,14 @@ public final class DictionaryCollection extends Dictionary {
}
@Override
- public boolean isValidWord(CharSequence word) {
+ public boolean isValidWord(final String word) {
for (int i = mDictionaries.size() - 1; i >= 0; --i)
if (mDictionaries.get(i).isValidWord(word)) return true;
return false;
}
@Override
- public int getFrequency(CharSequence word) {
+ public int getFrequency(final String word) {
int maxFreq = -1;
for (int i = mDictionaries.size() - 1; i >= 0; --i) {
final int tempFreq = mDictionaries.get(i).getFrequency(word);
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index b93c17f11..159867ade 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -198,7 +198,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override
public ArrayList getSuggestions(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo) {
+ final String prevWord, final ProximityInfo proximityInfo) {
asyncReloadDictionaryIfRequired();
if (mLocalDictionaryController.tryLock()) {
try {
@@ -213,12 +213,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
@Override
- public boolean isValidWord(final CharSequence word) {
+ public boolean isValidWord(final String word) {
asyncReloadDictionaryIfRequired();
return isValidWordInner(word);
}
- protected boolean isValidWordInner(final CharSequence word) {
+ protected boolean isValidWordInner(final String word) {
if (mLocalDictionaryController.tryLock()) {
try {
return isValidWordLocked(word);
@@ -229,17 +229,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return false;
}
- protected boolean isValidWordLocked(final CharSequence word) {
+ protected boolean isValidWordLocked(final String word) {
if (mBinaryDictionary == null) return false;
return mBinaryDictionary.isValidWord(word);
}
- protected boolean isValidBigram(final CharSequence word1, final CharSequence word2) {
+ protected boolean isValidBigram(final String word1, final String word2) {
if (mBinaryDictionary == null) return false;
return mBinaryDictionary.isValidBigram(word1, word2);
}
- protected boolean isValidBigramInner(final CharSequence word1, final CharSequence word2) {
+ protected boolean isValidBigramInner(final String word1, final String word2) {
if (mLocalDictionaryController.tryLock()) {
try {
return isValidBigramLocked(word1, word2);
@@ -250,7 +250,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return false;
}
- protected boolean isValidBigramLocked(final CharSequence word1, final CharSequence word2) {
+ protected boolean isValidBigramLocked(final String word1, final String word2) {
if (mBinaryDictionary == null) return false;
return mBinaryDictionary.isValidBigram(word1, word2);
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 8cdc2a0af..c96a802ce 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -69,7 +69,7 @@ public class ExpandableDictionary extends Dictionary {
mData = new Node[INCREMENT];
}
- void add(Node n) {
+ void add(final Node n) {
if (mLength + 1 > mData.length) {
Node[] tempData = new Node[mLength + INCREMENT];
if (mLength > 0) {
@@ -172,7 +172,7 @@ public class ExpandableDictionary extends Dictionary {
}
}
- public void setRequiresReload(boolean reload) {
+ public void setRequiresReload(final boolean reload) {
synchronized (mUpdatingLock) {
mRequiresReload = reload;
}
@@ -202,8 +202,8 @@ public class ExpandableDictionary extends Dictionary {
addWordRec(mRoots, word, 0, shortcutTarget, frequency, null);
}
- private void addWordRec(NodeArray children, final String word, final int depth,
- final String shortcutTarget, final int frequency, Node parentNode) {
+ private void addWordRec(final NodeArray children, final String word, final int depth,
+ final String shortcutTarget, final int frequency, final Node parentNode) {
final int wordLength = word.length();
if (wordLength <= depth) return;
final char c = word.charAt(depth);
@@ -248,7 +248,7 @@ public class ExpandableDictionary extends Dictionary {
@Override
public ArrayList getSuggestions(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo) {
+ final String prevWord, final ProximityInfo proximityInfo) {
if (reloadDictionaryIfRequired()) return null;
if (composer.size() > 1) {
if (composer.size() >= BinaryDictionary.MAX_WORD_LENGTH) {
@@ -277,7 +277,7 @@ public class ExpandableDictionary extends Dictionary {
}
protected ArrayList getWordsInner(final WordComposer codes,
- final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) {
+ final String prevWordForBigrams, final ProximityInfo proximityInfo) {
final ArrayList suggestions = CollectionUtils.newArrayList();
mInputLength = codes.size();
if (mCodes.length < mInputLength) mCodes = new int[mInputLength][];
@@ -305,7 +305,7 @@ public class ExpandableDictionary extends Dictionary {
}
@Override
- public synchronized boolean isValidWord(CharSequence word) {
+ public synchronized boolean isValidWord(final String word) {
synchronized (mUpdatingLock) {
// If we need to update, start off a background task
if (mRequiresReload) startDictionaryLoadingTaskLocked();
@@ -320,7 +320,7 @@ public class ExpandableDictionary extends Dictionary {
return (node == null) ? false : !node.mShortcutOnly;
}
- protected boolean removeBigram(String word1, String word2) {
+ protected boolean removeBigram(final String word1, final String word2) {
// Refer to addOrSetBigram() about word1.toLowerCase()
final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
final Node secondWord = searchWord(mRoots, word2, 0, null);
@@ -345,13 +345,13 @@ public class ExpandableDictionary extends Dictionary {
/**
* Returns the word's frequency or -1 if not found
*/
- protected int getWordFrequency(CharSequence word) {
+ protected int getWordFrequency(final String word) {
// Case-sensitive search
final Node node = searchNode(mRoots, word, 0, word.length());
return (node == null) ? -1 : node.mFrequency;
}
- protected NextWord getBigramWord(String word1, String word2) {
+ protected NextWord getBigramWord(final String word1, final String word2) {
// Refer to addOrSetBigram() about word1.toLowerCase()
final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null);
final Node secondWord = searchWord(mRoots, word2, 0, null);
@@ -368,7 +368,8 @@ public class ExpandableDictionary extends Dictionary {
return null;
}
- private static int computeSkippedWordFinalFreq(int freq, int snr, int inputLength) {
+ private static int computeSkippedWordFinalFreq(final int freq, final int snr,
+ final int inputLength) {
// The computation itself makes sense for >= 2, but the == 2 case returns 0
// anyway so we may as well test against 3 instead and return the constant
if (inputLength >= 3) {
@@ -431,9 +432,9 @@ public class ExpandableDictionary extends Dictionary {
* @param suggestions the list in which to add suggestions
*/
// TODO: Share this routine with the native code for BinaryDictionary
- protected void getWordsRec(NodeArray roots, final WordComposer codes, final char[] word,
- final int depth, final boolean completion, int snr, int inputIndex, int skipPos,
- final ArrayList suggestions) {
+ protected void getWordsRec(final NodeArray roots, final WordComposer codes, final char[] word,
+ final int depth, final boolean completion, final int snr, final int inputIndex,
+ final int skipPos, final ArrayList suggestions) {
final int count = roots.mLength;
final int codeSize = mInputLength;
// Optimization: Prune out words that are too long compared to how much was typed.
@@ -524,11 +525,13 @@ public class ExpandableDictionary extends Dictionary {
}
}
- public int setBigramAndGetFrequency(String word1, String word2, int frequency) {
+ public int setBigramAndGetFrequency(final String word1, final String word2,
+ final int frequency) {
return setBigramAndGetFrequency(word1, word2, frequency, null /* unused */);
}
- public int setBigramAndGetFrequency(String word1, String word2, ForgettingCurveParams fcp) {
+ public int setBigramAndGetFrequency(final String word1, final String word2,
+ final ForgettingCurveParams fcp) {
return setBigramAndGetFrequency(word1, word2, 0 /* unused */, fcp);
}
@@ -540,8 +543,8 @@ public class ExpandableDictionary extends Dictionary {
* @param fcp an instance of ForgettingCurveParams to use for decay policy
* @return returns the final bigram frequency
*/
- private int setBigramAndGetFrequency(
- String word1, String word2, int frequency, ForgettingCurveParams fcp) {
+ private int setBigramAndGetFrequency(final String word1, final String word2,
+ final int frequency, final ForgettingCurveParams fcp) {
// We don't want results to be different according to case of the looked up left hand side
// word. We do want however to return the correct case for the right hand side.
// So we want to squash the case of the left hand side, and preserve that of the right
@@ -572,7 +575,8 @@ public class ExpandableDictionary extends Dictionary {
* Searches for the word and add the word if it does not exist.
* @return Returns the terminal node of the word we are searching for.
*/
- private Node searchWord(NodeArray children, String word, int depth, Node parentNode) {
+ private Node searchWord(final NodeArray children, final String word, final int depth,
+ final Node parentNode) {
final int wordLength = word.length();
final char c = word.charAt(depth);
// Does children have the current character?
@@ -602,11 +606,11 @@ public class ExpandableDictionary extends Dictionary {
return searchWord(childNode.mChildren, word, depth + 1, childNode);
}
- private void runBigramReverseLookUp(final CharSequence previousWord,
+ private void runBigramReverseLookUp(final String previousWord,
final ArrayList suggestions) {
// Search for the lowercase version of the word only, because that's where bigrams
// store their sons.
- Node prevWord = searchNode(mRoots, previousWord.toString().toLowerCase(), 0,
+ final Node prevWord = searchNode(mRoots, previousWord.toLowerCase(), 0,
previousWord.length());
if (prevWord != null && prevWord.mNGrams != null) {
reverseLookUp(prevWord.mNGrams, suggestions);
@@ -641,7 +645,7 @@ public class ExpandableDictionary extends Dictionary {
* @param terminalNodes list of terminal nodes we want to add
* @param suggestions the suggestion collection to add the word to
*/
- private void reverseLookUp(LinkedList terminalNodes,
+ private void reverseLookUp(final LinkedList terminalNodes,
final ArrayList suggestions) {
Node node;
int freq;
@@ -714,7 +718,7 @@ public class ExpandableDictionary extends Dictionary {
}
}
- private static char toLowerCase(char c) {
+ private static char toLowerCase(final char c) {
char baseChar = c;
if (c < BASE_CHARS.length) {
baseChar = BASE_CHARS[c];
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
index 94cdc9b85..44ef01204 100644
--- a/java/src/com/android/inputmethod/latin/LastComposedWord.java
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -44,7 +44,7 @@ public final class LastComposedWord {
public final String mTypedWord;
public final String mCommittedWord;
public final String mSeparatorString;
- public final CharSequence mPrevWord;
+ public final String mPrevWord;
public final InputPointers mInputPointers = new InputPointers(BinaryDictionary.MAX_WORD_LENGTH);
private boolean mActive;
@@ -56,7 +56,7 @@ public final class LastComposedWord {
// immutable. Do not fiddle with their contents after you passed them to this constructor.
public LastComposedWord(final int[] primaryKeyCodes, final InputPointers inputPointers,
final String typedWord, final String committedWord,
- final String separatorString, final CharSequence prevWord) {
+ final String separatorString, final String prevWord) {
mPrimaryKeyCodes = primaryKeyCodes;
if (inputPointers != null) {
mInputPointers.copy(inputPointers);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4cf6a5112..a68ff6504 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -171,7 +171,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
new DictionaryPackInstallBroadcastReceiver(this);
// Keeps track of most recently inserted text (multi-character key) for reverting
- private CharSequence mEnteredText;
+ private String mEnteredText;
private boolean mIsAutoCorrectionIndicatorOn;
@@ -1093,7 +1093,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private void commitTyped(final String separatorString) {
if (!mWordComposer.isComposingWord()) return;
- final CharSequence typedWord = mWordComposer.getTypedWord();
+ final String typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) {
commitChosenWord(typedWord, LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD,
separatorString);
@@ -1379,7 +1379,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Called from PointerTracker through the KeyboardActionListener interface
@Override
- public void onTextInput(final CharSequence rawText) {
+ public void onTextInput(final String rawText) {
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
commitCurrentAutoCorrection(rawText.toString());
@@ -1387,7 +1387,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
resetComposingState(true /* alsoResetLastComposedWord */);
}
mHandler.postUpdateSuggestionStrip();
- final CharSequence text = specificTldProcessingOnTextInput(rawText);
+ final String text = specificTldProcessingOnTextInput(rawText);
if (SPACE_STATE_PHANTOM == mSpaceState) {
sendKeyCodePoint(Keyboard.CODE_SPACE);
}
@@ -1558,7 +1558,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mKeyboardSwitcher.updateShiftState();
}
- private CharSequence specificTldProcessingOnTextInput(final CharSequence text) {
+ private String specificTldProcessingOnTextInput(final String text) {
if (text.length() <= 1 || text.charAt(0) != Keyboard.CODE_PERIOD
|| !Character.isLetter(text.charAt(1))) {
// Not a tld: do nothing.
@@ -1571,7 +1571,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final CharSequence lastOne = mConnection.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
&& lastOne.charAt(0) == Keyboard.CODE_PERIOD) {
- return text.subSequence(1, text.length());
+ return text.substring(1);
} else {
return text;
}
@@ -1831,7 +1831,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
return didAutoCorrect;
}
- private CharSequence getTextWithUnderline(final CharSequence text) {
+ private CharSequence getTextWithUnderline(final String text) {
return mIsAutoCorrectionIndicatorOn
? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(this, text)
: text;
@@ -1926,7 +1926,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
// should just skip whitespace if any, so 1.
// TODO: this is slow (2-way IPC) - we should probably cache this instead.
- final CharSequence prevWord =
+ final String prevWord =
mConnection.getNthPreviousWord(mCurrentSettings.mWordSeparators,
mWordComposer.isComposingWord() ? 2 : 1);
final SuggestedWords suggestedWords = mSuggest.getSuggestedWords(mWordComposer,
@@ -1935,7 +1935,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
return maybeRetrieveOlderSuggestions(typedWord, suggestedWords);
}
- private SuggestedWords maybeRetrieveOlderSuggestions(final CharSequence typedWord,
+ private SuggestedWords maybeRetrieveOlderSuggestions(final String typedWord,
final SuggestedWords suggestedWords) {
// TODO: consolidate this into getSuggestedWords
// We update the suggestion strip only when we have some suggestions to show, i.e. when
@@ -1965,13 +1965,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
}
- private void showSuggestionStrip(final SuggestedWords suggestedWords,
- final CharSequence typedWord) {
+ private void showSuggestionStrip(final SuggestedWords suggestedWords, final String typedWord) {
if (suggestedWords.isEmpty()) {
clearSuggestionStrip();
return;
}
- final CharSequence autoCorrection;
+ final String autoCorrection;
if (suggestedWords.mWillAutoCorrect) {
autoCorrection = suggestedWords.getWord(1);
} else {
@@ -1989,9 +1988,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (mHandler.hasPendingUpdateSuggestions()) {
updateSuggestionStrip();
}
- final CharSequence typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
+ final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
final String typedWord = mWordComposer.getTypedWord();
- final CharSequence autoCorrection = (typedAutoCorrection != null)
+ final String autoCorrection = (typedAutoCorrection != null)
? typedAutoCorrection : typedWord;
if (autoCorrection != null) {
if (TextUtils.isEmpty(typedWord)) {
@@ -2022,7 +2021,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Called from {@link SuggestionStripView} through the {@link SuggestionStripView#Listener}
// interface
@Override
- public void pickSuggestionManually(final int index, final CharSequence suggestion) {
+ public void pickSuggestionManually(final int index, final String suggestion) {
final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
// If this is a punctuation picked from the suggestion strip, pass it to onCodeInput
if (suggestion.length() == 1 && isShowingPunctuationList()) {
@@ -2107,13 +2106,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
/**
* Commits the chosen word to the text field and saves it for later retrieval.
*/
- private void commitChosenWord(final CharSequence chosenWord, final int commitType,
+ private void commitChosenWord(final String chosenWord, final int commitType,
final String separatorString) {
final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1);
// Add the word to the user history dictionary
- final CharSequence prevWord = addToUserHistoryDictionary(chosenWord);
+ final String prevWord = addToUserHistoryDictionary(chosenWord);
// TODO: figure out here if this is an auto-correct or if the best word is actually
// what user typed. Note: currently this is done much later in
// LastComposedWord#didCommitTypedWord by string equality of the remembered
@@ -2132,7 +2131,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
setSuggestionStripShown(isSuggestionsStripVisible());
}
- private CharSequence addToUserHistoryDictionary(final CharSequence suggestion) {
+ private String addToUserHistoryDictionary(final String suggestion) {
if (TextUtils.isEmpty(suggestion)) return null;
if (mSuggest == null) return null;
@@ -2147,19 +2146,18 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
= mConnection.getNthPreviousWord(mCurrentSettings.mWordSeparators, 2);
final String secondWord;
if (mWordComposer.wasAutoCapitalized() && !mWordComposer.isMostlyCaps()) {
- secondWord = suggestion.toString().toLowerCase(
- mSubtypeSwitcher.getCurrentSubtypeLocale());
+ secondWord = suggestion.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale());
} else {
- secondWord = suggestion.toString();
+ secondWord = suggestion;
}
// We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
// We don't add words with 0-frequency (assuming they would be profanity etc.).
final int maxFreq = AutoCorrection.getMaxFrequency(
mSuggest.getUnigramDictionaries(), suggestion);
if (maxFreq == 0) return null;
- userHistoryDictionary.addToUserHistory(null == prevWord ? null : prevWord.toString(),
- secondWord, maxFreq > 0);
- return prevWord;
+ final String prevWordString = (null == prevWord) ? null : prevWord.toString();
+ userHistoryDictionary.addToUserHistory(prevWordString, secondWord, maxFreq > 0);
+ return prevWordString;
}
return null;
}
@@ -2184,9 +2182,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
private void revertCommit() {
- final CharSequence previousWord = mLastComposedWord.mPrevWord;
+ final String previousWord = mLastComposedWord.mPrevWord;
final String originallyTypedWord = mLastComposedWord.mTypedWord;
- final CharSequence committedWord = mLastComposedWord.mCommittedWord;
+ final String committedWord = mLastComposedWord.mCommittedWord;
final int cancelLength = committedWord.length();
final int separatorLength = LastComposedWord.getSeparatorLength(
mLastComposedWord.mSeparatorString);
@@ -2196,9 +2194,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (mWordComposer.isComposingWord()) {
throw new RuntimeException("revertCommit, but we are composing a word");
}
- final String wordBeforeCursor =
+ final CharSequence wordBeforeCursor =
mConnection.getTextBeforeCursor(deleteLength, 0)
- .subSequence(0, cancelLength).toString();
+ .subSequence(0, cancelLength);
if (!TextUtils.equals(committedWord, wordBeforeCursor)) {
throw new RuntimeException("revertCommit check failed: we thought we were "
+ "reverting \"" + committedWord
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 21441369e..bf2dfbc0b 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -398,7 +398,7 @@ public final class RichInputConnection {
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
- public CharSequence getNthPreviousWord(final String sentenceSeperators, final int n) {
+ public String getNthPreviousWord(final String sentenceSeperators, final int n) {
mIC = mParent.getCurrentInputConnection();
if (null == mIC) return null;
final CharSequence prev = mIC.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
@@ -466,19 +466,22 @@ public final class RichInputConnection {
// (n = 2) "abc|" -> null
// (n = 2) "abc |" -> null
// (n = 2) "abc. def|" -> null
- public static CharSequence getNthPreviousWord(final CharSequence prev,
+ public static String getNthPreviousWord(final CharSequence prev,
final String sentenceSeperators, final int n) {
if (prev == null) return null;
- String[] w = spaceRegex.split(prev);
+ final String[] w = spaceRegex.split(prev);
// If we can't find n words, or we found an empty word, return null.
- if (w.length < n || w[w.length - n].length() <= 0) return null;
+ if (w.length < n) return null;
+ final String nthPrevWord = w[w.length - n];
+ final int length = nthPrevWord.length();
+ if (length <= 0) return null;
// If ends in a separator, return null
- char lastChar = w[w.length - n].charAt(w[w.length - n].length() - 1);
+ final char lastChar = nthPrevWord.charAt(length - 1);
if (sentenceSeperators.contains(String.valueOf(lastChar))) return null;
- return w[w.length - n];
+ return nthPrevWord;
}
/**
@@ -511,19 +514,20 @@ public final class RichInputConnection {
* be included in the returned range
* @return a range containing the text surrounding the cursor
*/
- public Range getWordRangeAtCursor(String sep, int additionalPrecedingWordsCount) {
+ public Range getWordRangeAtCursor(final String sep, final int additionalPrecedingWordsCount) {
mIC = mParent.getCurrentInputConnection();
if (mIC == null || sep == null) {
return null;
}
- CharSequence before = mIC.getTextBeforeCursor(1000, 0);
- CharSequence after = mIC.getTextAfterCursor(1000, 0);
+ final CharSequence before = mIC.getTextBeforeCursor(1000, 0);
+ final CharSequence after = mIC.getTextAfterCursor(1000, 0);
if (before == null || after == null) {
return null;
}
// Going backward, alternate skipping non-separators and separators until enough words
// have been read.
+ int count = additionalPrecedingWordsCount;
int start = before.length();
boolean isStoppingAtWhitespace = true; // toggles to indicate what to stop at
while (true) { // see comments below for why this is guaranteed to halt
@@ -540,7 +544,7 @@ public final class RichInputConnection {
// isStoppingAtWhitespace is true every other time through the loop,
// so additionalPrecedingWordsCount is guaranteed to become < 0, which
// guarantees outer loop termination
- if (isStoppingAtWhitespace && (--additionalPrecedingWordsCount < 0)) {
+ if (isStoppingAtWhitespace && (--count < 0)) {
break; // outer loop
}
isStoppingAtWhitespace = !isStoppingAtWhitespace;
@@ -558,7 +562,7 @@ public final class RichInputConnection {
}
}
- int cursor = getCursorPosition();
+ final int cursor = getCursorPosition();
if (start >= 0 && cursor + end <= after.length() + before.length()) {
String word = before.toString().substring(start, before.length())
+ after.toString().substring(0, end);
@@ -569,8 +573,8 @@ public final class RichInputConnection {
}
public boolean isCursorTouchingWord(final SettingsValues settingsValues) {
- CharSequence before = getTextBeforeCursor(1, 0);
- CharSequence after = getTextAfterCursor(1, 0);
+ final CharSequence before = getTextBeforeCursor(1, 0);
+ final CharSequence after = getTextAfterCursor(1, 0);
if (!TextUtils.isEmpty(before) && !settingsValues.isWordSeparator(before.charAt(0))
&& !settingsValues.isSymbolExcludedFromWordSeparators(before.charAt(0))) {
return true;
diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java
index df7709892..44b75b568 100644
--- a/java/src/com/android/inputmethod/latin/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/StringUtils.java
@@ -16,9 +16,11 @@
package com.android.inputmethod.latin;
+import android.text.InputType;
import android.text.TextUtils;
-import com.android.inputmethod.keyboard.Keyboard; // For character constants
+//For character constants
+import com.android.inputmethod.keyboard.Keyboard;
import java.util.ArrayList;
import java.util.Locale;
@@ -28,30 +30,30 @@ public final class StringUtils {
// This utility class is not publicly instantiable.
}
- public static int codePointCount(String text) {
+ public static int codePointCount(final String text) {
if (TextUtils.isEmpty(text)) return 0;
return text.codePointCount(0, text.length());
}
- public static boolean containsInArray(String key, String[] array) {
+ public static boolean containsInArray(final String key, final String[] array) {
for (final String element : array) {
if (key.equals(element)) return true;
}
return false;
}
- public static boolean containsInCsv(String key, String csv) {
+ public static boolean containsInCsv(final String key, final String csv) {
if (TextUtils.isEmpty(csv)) return false;
return containsInArray(key, csv.split(","));
}
- public static String appendToCsvIfNotExists(String key, String csv) {
+ public static String appendToCsvIfNotExists(final String key, final String csv) {
if (TextUtils.isEmpty(csv)) return key;
if (containsInCsv(key, csv)) return csv;
return csv + "," + key;
}
- public static String removeFromCsvIfExists(String key, String csv) {
+ public static String removeFromCsvIfExists(final String key, final String csv) {
if (TextUtils.isEmpty(csv)) return "";
final String[] elements = csv.split(",");
if (!containsInArray(key, elements)) return csv;
@@ -62,83 +64,21 @@ public final class StringUtils {
return TextUtils.join(",", result);
}
- /**
- * Returns true if a and b are equal ignoring the case of the character.
- * @param a first character to check
- * @param b second character to check
- * @return {@code true} if a and b are equal, {@code false} otherwise.
- */
- public static boolean equalsIgnoreCase(char a, char b) {
- // Some language, such as Turkish, need testing both cases.
- return a == b
- || Character.toLowerCase(a) == Character.toLowerCase(b)
- || Character.toUpperCase(a) == Character.toUpperCase(b);
- }
-
- /**
- * Returns true if a and b are equal ignoring the case of the characters, including if they are
- * both null.
- * @param a first CharSequence to check
- * @param b second CharSequence to check
- * @return {@code true} if a and b are equal, {@code false} otherwise.
- */
- public static boolean equalsIgnoreCase(CharSequence a, CharSequence b) {
- if (a == b)
- return true; // including both a and b are null.
- if (a == null || b == null)
- return false;
- final int length = a.length();
- if (length != b.length())
- return false;
- for (int i = 0; i < length; i++) {
- if (!equalsIgnoreCase(a.charAt(i), b.charAt(i)))
- return false;
- }
- return true;
- }
-
- /**
- * Returns true if a and b are equal ignoring the case of the characters, including if a is null
- * and b is zero length.
- * @param a CharSequence to check
- * @param b character array to check
- * @param offset start offset of array b
- * @param length length of characters in array b
- * @return {@code true} if a and b are equal, {@code false} otherwise.
- * @throws IndexOutOfBoundsException
- * if {@code offset < 0 || length < 0 || offset + length > data.length}.
- * @throws NullPointerException if {@code b == null}.
- */
- public static boolean equalsIgnoreCase(CharSequence a, char[] b, int offset, int length) {
- if (offset < 0 || length < 0 || length > b.length - offset)
- throw new IndexOutOfBoundsException("array.length=" + b.length + " offset=" + offset
- + " length=" + length);
- if (a == null)
- return length == 0; // including a is null and b is zero length.
- if (a.length() != length)
- return false;
- for (int i = 0; i < length; i++) {
- if (!equalsIgnoreCase(a.charAt(i), b[offset + i]))
- return false;
- }
- return true;
- }
-
/**
* Remove duplicates from an array of strings.
*
* This method will always keep the first occurrence of all strings at their position
* in the array, removing the subsequent ones.
*/
- public static void removeDupes(final ArrayList suggestions) {
+ public static void removeDupes(final ArrayList suggestions) {
if (suggestions.size() < 2) return;
int i = 1;
// Don't cache suggestions.size(), since we may be removing items
while (i < suggestions.size()) {
- final CharSequence cur = suggestions.get(i);
+ final String cur = suggestions.get(i);
// Compare each suggestion with each previous suggestion
for (int j = 0; j < i; j++) {
- CharSequence previous = suggestions.get(j);
+ final String previous = suggestions.get(j);
if (TextUtils.equals(cur, previous)) {
suggestions.remove(i);
i--;
@@ -149,7 +89,7 @@ public final class StringUtils {
}
}
- public static String toTitleCase(String s, Locale locale) {
+ public static String toTitleCase(final String s, final Locale locale) {
if (s.length() <= 1) {
// TODO: is this really correct? Shouldn't this be s.toUpperCase()?
return s;
@@ -165,21 +105,19 @@ public final class StringUtils {
return s.toUpperCase(locale).charAt(0) + s.substring(1);
}
+ private static final int[] EMPTY_CODEPOINTS = {};
+
public static int[] toCodePointArray(final String string) {
- final char[] characters = string.toCharArray();
- final int length = characters.length;
- final int[] codePoints = new int[Character.codePointCount(characters, 0, length)];
+ final int length = string.length();
if (length <= 0) {
- return new int[0];
+ return EMPTY_CODEPOINTS;
}
- int codePoint = Character.codePointAt(characters, 0);
- int dsti = 0;
- for (int srci = Character.charCount(codePoint);
- srci < length; srci += Character.charCount(codePoint), ++dsti) {
- codePoints[dsti] = codePoint;
- codePoint = Character.codePointAt(characters, srci);
+ final int[] codePoints = new int[string.codePointCount(0, length)];
+ int destIndex = 0;
+ for (int index = 0; index < length; index = string.offsetByCodePoints(index, 1)) {
+ codePoints[destIndex] = string.codePointAt(index);
+ destIndex++;
}
- codePoints[dsti] = codePoint;
return codePoints;
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index f0e3b4ebd..7e03cdb9c 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -38,7 +38,7 @@ public final class Suggest {
public static final String TAG = Suggest.class.getSimpleName();
// Session id for
- // {@link #getSuggestedWords(WordComposer,CharSequence,ProximityInfo,boolean,int)}.
+ // {@link #getSuggestedWords(WordComposer,String,ProximityInfo,boolean,int)}.
public static final int SESSION_TYPING = 0;
public static final int SESSION_GESTURE = 1;
@@ -138,7 +138,7 @@ public final class Suggest {
* Sets an optional user dictionary resource to be loaded. The user dictionary is consulted
* before the main dictionary, if set. This refers to the system-managed user dictionary.
*/
- public void setUserDictionary(UserBinaryDictionary userDictionary) {
+ public void setUserDictionary(final UserBinaryDictionary userDictionary) {
addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER, userDictionary);
}
@@ -147,12 +147,12 @@ public final class Suggest {
* the contacts dictionary by passing null to this method. In this case no contacts dictionary
* won't be used.
*/
- public void setContactsDictionary(ContactsBinaryDictionary contactsDictionary) {
+ public void setContactsDictionary(final ContactsBinaryDictionary contactsDictionary) {
mContactsDict = contactsDictionary;
addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_CONTACTS, contactsDictionary);
}
- public void setUserHistoryDictionary(UserHistoryDictionary userHistoryDictionary) {
+ public void setUserHistoryDictionary(final UserHistoryDictionary userHistoryDictionary) {
addOrReplaceDictionary(mDictionaries, Dictionary.TYPE_USER_HISTORY, userHistoryDictionary);
}
@@ -160,9 +160,9 @@ public final class Suggest {
mAutoCorrectionThreshold = threshold;
}
- public SuggestedWords getSuggestedWords(
- final WordComposer wordComposer, CharSequence prevWordForBigram,
- final ProximityInfo proximityInfo, final boolean isCorrectionEnabled, int sessionId) {
+ public SuggestedWords getSuggestedWords(final WordComposer wordComposer,
+ final String prevWordForBigram, final ProximityInfo proximityInfo,
+ final boolean isCorrectionEnabled, final int sessionId) {
LatinImeLogger.onStartSuggestion(prevWordForBigram);
if (wordComposer.isBatchMode()) {
return getSuggestedWordsForBatchInput(
@@ -174,9 +174,9 @@ public final class Suggest {
}
// Retrieves suggestions for the typing input.
- private SuggestedWords getSuggestedWordsForTypingInput(
- final WordComposer wordComposer, CharSequence prevWordForBigram,
- final ProximityInfo proximityInfo, final boolean isCorrectionEnabled) {
+ private SuggestedWords getSuggestedWordsForTypingInput(final WordComposer wordComposer,
+ final String prevWordForBigram, final ProximityInfo proximityInfo,
+ final boolean isCorrectionEnabled) {
final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
MAX_SUGGESTIONS);
@@ -203,7 +203,7 @@ public final class Suggest {
wordComposerForLookup, prevWordForBigram, proximityInfo));
}
- final CharSequence whitelistedWord;
+ final String whitelistedWord;
if (suggestionsSet.isEmpty()) {
whitelistedWord = null;
} else if (SuggestedWordInfo.KIND_WHITELIST != suggestionsSet.first().mKind) {
@@ -287,9 +287,9 @@ public final class Suggest {
}
// Retrieves suggestions for the batch input.
- private SuggestedWords getSuggestedWordsForBatchInput(
- final WordComposer wordComposer, CharSequence prevWordForBigram,
- final ProximityInfo proximityInfo, int sessionId) {
+ private SuggestedWords getSuggestedWordsForBatchInput(final WordComposer wordComposer,
+ final String prevWordForBigram, final ProximityInfo proximityInfo,
+ final int sessionId) {
final BoundedTreeSet suggestionsSet = new BoundedTreeSet(sSuggestedWordInfoComparator,
MAX_SUGGESTIONS);
@@ -307,7 +307,7 @@ public final class Suggest {
}
for (SuggestedWordInfo wordInfo : suggestionsSet) {
- LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(), wordInfo.mSourceDict);
+ LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict);
}
final ArrayList suggestionsContainer =
@@ -372,7 +372,7 @@ public final class Suggest {
if (o1.mScore < o2.mScore) return 1;
if (o1.mCodePointCount < o2.mCodePointCount) return -1;
if (o1.mCodePointCount > o2.mCodePointCount) return 1;
- return o1.mWord.toString().compareTo(o2.mWord.toString());
+ return o1.mWord.compareTo(o2.mWord);
}
}
private static final SuggestedWordInfoComparator sSuggestedWordInfoComparator =
@@ -383,16 +383,17 @@ public final class Suggest {
final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) {
final StringBuilder sb = new StringBuilder(wordInfo.mWord.length());
if (isAllUpperCase) {
- sb.append(wordInfo.mWord.toString().toUpperCase(locale));
+ sb.append(wordInfo.mWord.toUpperCase(locale));
} else if (isFirstCharCapitalized) {
- sb.append(StringUtils.toTitleCase(wordInfo.mWord.toString(), locale));
+ sb.append(StringUtils.toTitleCase(wordInfo.mWord, locale));
} else {
sb.append(wordInfo.mWord);
}
for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
}
- return new SuggestedWordInfo(sb, wordInfo.mScore, wordInfo.mKind, wordInfo.mSourceDict);
+ return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKind,
+ wordInfo.mSourceDict);
}
public void close() {
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index ad94affb2..572f2906e 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -90,11 +90,14 @@ public final class SuggestedWords {
public static ArrayList getFromApplicationSpecifiedCompletions(
final CompletionInfo[] infos) {
final ArrayList result = CollectionUtils.newArrayList();
- for (CompletionInfo info : infos) {
- if (null != info && info.getText() != null) {
- result.add(new SuggestedWordInfo(info.getText(), SuggestedWordInfo.MAX_SCORE,
- SuggestedWordInfo.KIND_APP_DEFINED, Dictionary.TYPE_APPLICATION_DEFINED));
- }
+ for (final CompletionInfo info : infos) {
+ if (info == null) continue;
+ final CharSequence text = info.getText();
+ if (null == text) continue;
+ final SuggestedWordInfo suggestedWordInfo = new SuggestedWordInfo(text.toString(),
+ SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_APP_DEFINED,
+ Dictionary.TYPE_APPLICATION_DEFINED);
+ result.add(suggestedWordInfo);
}
return result;
}
@@ -102,7 +105,7 @@ public final class SuggestedWords {
// Should get rid of the first one (what the user typed previously) from suggestions
// and replace it with what the user currently typed.
public static ArrayList getTypedWordAndPreviousSuggestions(
- final CharSequence typedWord, final SuggestedWords previousSuggestions) {
+ final String typedWord, final SuggestedWords previousSuggestions) {
final ArrayList suggestionsList = CollectionUtils.newArrayList();
final HashSet alreadySeen = CollectionUtils.newHashSet();
suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE,
@@ -111,7 +114,7 @@ public final class SuggestedWords {
final int previousSize = previousSuggestions.size();
for (int pos = 1; pos < previousSize; pos++) {
final SuggestedWordInfo prevWordInfo = previousSuggestions.getWordInfo(pos);
- final String prevWord = prevWordInfo.mWord.toString();
+ final String prevWord = prevWordInfo.mWord;
// Filter out duplicate suggestion.
if (!alreadySeen.contains(prevWord)) {
suggestionsList.add(prevWordInfo);
@@ -139,9 +142,9 @@ public final class SuggestedWords {
public final String mSourceDict;
private String mDebugString = "";
- public SuggestedWordInfo(final CharSequence word, final int score, final int kind,
+ public SuggestedWordInfo(final String word, final int score, final int kind,
final String sourceDict) {
- mWord = word.toString();
+ mWord = word;
mScore = score;
mKind = kind;
mSourceDict = sourceDict;
@@ -149,7 +152,7 @@ public final class SuggestedWords {
}
- public void setDebugString(String str) {
+ public void setDebugString(final String str) {
if (null == str) throw new NullPointerException("Debug info is null");
mDebugString = str;
}
@@ -171,7 +174,7 @@ public final class SuggestedWords {
if (TextUtils.isEmpty(mDebugString)) {
return mWord;
} else {
- return mWord + " (" + mDebugString.toString() + ")";
+ return mWord + " (" + mDebugString + ")";
}
}
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
index 8f21b7b4a..ec4dc1436 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -33,13 +33,13 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB
@Override
public synchronized ArrayList getSuggestions(final WordComposer codes,
- final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) {
+ final String prevWordForBigrams, final ProximityInfo proximityInfo) {
syncReloadDictionaryIfRequired();
return super.getSuggestions(codes, prevWordForBigrams, proximityInfo);
}
@Override
- public synchronized boolean isValidWord(CharSequence word) {
+ public synchronized boolean isValidWord(final String word) {
syncReloadDictionaryIfRequired();
return isValidWordInner(word);
}
diff --git a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
index 612f54d73..4bdaf2039 100644
--- a/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/SynchronouslyLoadedUserBinaryDictionary.java
@@ -36,13 +36,13 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic
@Override
public synchronized ArrayList getSuggestions(final WordComposer codes,
- final CharSequence prevWordForBigrams, final ProximityInfo proximityInfo) {
+ final String prevWordForBigrams, final ProximityInfo proximityInfo) {
syncReloadDictionaryIfRequired();
return super.getSuggestions(codes, prevWordForBigrams, proximityInfo);
}
@Override
- public synchronized boolean isValidWord(CharSequence word) {
+ public synchronized boolean isValidWord(final String word) {
syncReloadDictionaryIfRequired();
return isValidWordInner(word);
}
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 60e6fa127..00c3cbe0a 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -200,7 +200,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
mContext.startActivity(intent);
}
- private void addWords(Cursor cursor) {
+ private void addWords(final Cursor cursor) {
// 16 is JellyBean, but we want this to compile against ICS.
final boolean hasShortcutColumn = android.os.Build.VERSION.SDK_INT >= 16;
clearFusionDictionary();
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
index 3615fa1fb..a80a64267 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
@@ -122,7 +122,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
@Override
protected ArrayList getWordsInner(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo) {
+ final String prevWord, final ProximityInfo proximityInfo) {
// Inhibit suggestions (not predictions) for user history for now. Removing this method
// is enough to use it through the standard ExpandableDictionary way.
return null;
@@ -132,7 +132,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
* Return whether the passed charsequence is in the dictionary.
*/
@Override
- public synchronized boolean isValidWord(final CharSequence word) {
+ public synchronized boolean isValidWord(final String word) {
// TODO: figure out what is the correct thing to do here.
return false;
}
@@ -145,7 +145,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
* context, as in beginning of a sentence for example.
* The second word may not be null (a NullPointerException would be thrown).
*/
- public int addToUserHistory(final String word1, String word2, boolean isValid) {
+ public int addToUserHistory(final String word1, final String word2, final boolean isValid) {
if (word2.length() >= BinaryDictionary.MAX_WORD_LENGTH ||
(word1 != null && word1.length() >= BinaryDictionary.MAX_WORD_LENGTH)) {
return -1;
@@ -175,7 +175,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
return -1;
}
- public boolean cancelAddingUserHistory(String word1, String word2) {
+ public boolean cancelAddingUserHistory(final String word1, final String word2) {
if (mBigramListLock.tryLock()) {
try {
if (mBigramList.removeBigram(word1, word2)) {
@@ -226,7 +226,8 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
final ExpandableDictionary dictionary = this;
final OnAddWordListener listener = new OnAddWordListener() {
@Override
- public void setUnigram(String word, String shortcutTarget, int frequency) {
+ public void setUnigram(final String word, final String shortcutTarget,
+ final int frequency) {
profTotal++;
if (DBG_SAVE_RESTORE) {
Log.d(TAG, "load unigram: " + word + "," + frequency);
@@ -236,7 +237,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
}
@Override
- public void setBigram(String word1, String word2, int frequency) {
+ public void setBigram(final String word1, final String word2, final int frequency) {
if (word1.length() < BinaryDictionary.MAX_WORD_LENGTH
&& word2.length() < BinaryDictionary.MAX_WORD_LENGTH) {
profTotal++;
@@ -250,7 +251,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
mBigramList.addBigram(word1, word2, (byte)frequency);
}
};
-
+
// Load the dictionary from binary file
FileInputStream inStream = null;
try {
@@ -292,8 +293,9 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
private final SharedPreferences mPrefs;
private final Context mContext;
- public UpdateBinaryTask(UserHistoryDictionaryBigramList pendingWrites, String locale,
- UserHistoryDictionary dict, SharedPreferences prefs, Context context) {
+ public UpdateBinaryTask(final UserHistoryDictionaryBigramList pendingWrites,
+ final String locale, final UserHistoryDictionary dict,
+ final SharedPreferences prefs, final Context context) {
mBigramList = pendingWrites;
mLocale = locale;
mUserHistoryDictionary = dict;
@@ -303,7 +305,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
}
@Override
- protected Void doInBackground(Void... v) {
+ protected Void doInBackground(final Void... v) {
if (mUserHistoryDictionary.isTest) {
// If isTest == true, wait until the lock is released.
mUserHistoryDictionary.mBigramListLock.lock();
@@ -360,7 +362,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
}
@Override
- public int getFrequency(String word1, String word2) {
+ public int getFrequency(final String word1, final String word2) {
final int freq;
if (word1 == null) { // unigram
freq = FREQUENCY_FOR_TYPED;
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index da0071adc..229aa8a48 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -38,7 +38,7 @@ public final class WordComposer {
private int[] mPrimaryKeyCodes;
private final InputPointers mInputPointers = new InputPointers(N);
private final StringBuilder mTypedWord;
- private CharSequence mAutoCorrection;
+ private String mAutoCorrection;
private boolean mIsResumed;
private boolean mIsBatchMode;
@@ -64,7 +64,7 @@ public final class WordComposer {
refreshSize();
}
- public WordComposer(WordComposer source) {
+ public WordComposer(final WordComposer source) {
mPrimaryKeyCodes = Arrays.copyOf(source.mPrimaryKeyCodes, source.mPrimaryKeyCodes.length);
mTypedWord = new StringBuilder(source.mTypedWord);
mInputPointers.copy(source.mInputPointers);
@@ -121,7 +121,8 @@ public final class WordComposer {
return mInputPointers;
}
- private static boolean isFirstCharCapitalized(int index, int codePoint, boolean previous) {
+ private static boolean isFirstCharCapitalized(final int index, final int codePoint,
+ final boolean previous) {
if (index == 0) return Character.isUpperCase(codePoint);
return previous && !Character.isUpperCase(codePoint);
}
@@ -129,7 +130,7 @@ public final class WordComposer {
/**
* Add a new keystroke, with the pressed key's code point with the touch point coordinates.
*/
- public void add(int primaryCode, int keyX, int keyY) {
+ public void add(final int primaryCode, final int keyX, final int keyY) {
final int newIndex = size();
mTypedWord.appendCodePoint(primaryCode);
refreshSize();
@@ -156,12 +157,12 @@ public final class WordComposer {
mAutoCorrection = null;
}
- public void setBatchInputPointers(InputPointers batchPointers) {
+ public void setBatchInputPointers(final InputPointers batchPointers) {
mInputPointers.set(batchPointers);
mIsBatchMode = true;
}
- public void setBatchInputWord(CharSequence word) {
+ public void setBatchInputWord(final String word) {
reset();
mIsBatchMode = true;
final int length = word.length();
@@ -321,14 +322,14 @@ public final class WordComposer {
/**
* Sets the auto-correction for this word.
*/
- public void setAutoCorrection(final CharSequence correction) {
+ public void setAutoCorrection(final String correction) {
mAutoCorrection = correction;
}
/**
* @return the auto-correction for this word, or null if none.
*/
- public CharSequence getAutoCorrectionOrNull() {
+ public String getAutoCorrectionOrNull() {
return mAutoCorrection;
}
@@ -341,7 +342,7 @@ public final class WordComposer {
// `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
public LastComposedWord commitWord(final int type, final String committedWord,
- final String separatorString, final CharSequence prevWord) {
+ final String separatorString, final String prevWord) {
// Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK
// or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate
// the last composed word to ensure this does not happen.
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 5a11ae534..49b98863f 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -212,7 +212,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
}
}
- private final ArrayList mSuggestions;
+ private final ArrayList mSuggestions;
private final int[] mScores;
private final String mOriginalText;
private final float mSuggestionThreshold;
@@ -335,7 +335,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
gatheredSuggestions = mSuggestions.toArray(EMPTY_STRING_ARRAY);
final int bestScore = mScores[mLength - 1];
- final CharSequence bestSuggestion = mSuggestions.get(0);
+ final String bestSuggestion = mSuggestions.get(0);
final float normalizedScore =
BinaryDictionary.calcNormalizedScore(
mOriginalText, bestSuggestion.toString(), bestScore);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 53ed4d3c3..a8f323999 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -268,7 +268,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
dictInfo.mDictionary.getSuggestions(composer, prevWord,
dictInfo.mProximityInfo);
for (final SuggestedWordInfo suggestion : suggestions) {
- final String suggestionStr = suggestion.mWord.toString();
+ final String suggestionStr = suggestion.mWord;
suggestionsGatherer.addWord(suggestionStr.toCharArray(), null, 0,
suggestionStr.length(), suggestion.mScore);
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index 1fb2bbb6a..eae5d2e60 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -51,11 +51,11 @@ public final class DictionaryPool extends LinkedBlockingQueue
new Dictionary(Dictionary.TYPE_MAIN) {
@Override
public ArrayList getSuggestions(final WordComposer composer,
- final CharSequence prevWord, final ProximityInfo proximityInfo) {
+ final String prevWord, final ProximityInfo proximityInfo) {
return noSuggestions;
}
@Override
- public boolean isValidWord(CharSequence word) {
+ public boolean isValidWord(final String word) {
// This is never called. However if for some strange reason it ever gets
// called, returning true is less destructive (it will not underline the
// word in red).
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index 42626951d..35d5a0067 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -65,7 +65,7 @@ public final class MoreSuggestions extends Keyboard {
int pos = fromPos, rowStartPos = fromPos;
final int size = Math.min(suggestions.size(), SuggestionStripView.MAX_SUGGESTIONS);
while (pos < size) {
- final String word = suggestions.getWord(pos).toString();
+ final String word = suggestions.getWord(pos);
// TODO: Should take care of text x-scaling.
mWidths[pos] = (int)view.getLabelWidth(word, paint) + padding;
final int numColumn = pos - rowStartPos + 1;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 3cf5857fc..e7cb97fc2 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -77,7 +77,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
OnLongClickListener {
public interface Listener {
public boolean addWordToUserDictionary(String word);
- public void pickSuggestionManually(int index, CharSequence word);
+ public void pickSuggestionManually(int index, String word);
}
// The maximum number of suggestions available. See {@link Suggest#mPrefMaxSuggestions}.
@@ -286,7 +286,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private CharSequence getStyledSuggestionWord(final SuggestedWords suggestedWords,
final int pos) {
- final CharSequence word = suggestedWords.getWord(pos);
+ final String word = suggestedWords.getWord(pos);
final boolean isAutoCorrect = pos == 1 && suggestedWords.willAutoCorrect();
final boolean isTypedWordValid = pos == 0 && suggestedWords.mTypedWordValid;
if (!isAutoCorrect && !isTypedWordValid)
@@ -338,7 +338,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
// is in slot 1.
if (index == mCenterSuggestionIndex
&& AutoCorrection.shouldBlockAutoCorrectionBySafetyNet(
- suggestedWords.getWord(1).toString(), suggestedWords.getWord(0))) {
+ suggestedWords.getWord(1), suggestedWords.getWord(0))) {
return 0xFFFF0000;
}
}
@@ -409,7 +409,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
x += word.getMeasuredWidth();
if (DBG && pos < suggestedWords.size()) {
- final CharSequence debugInfo = Utils.getDebugInfo(suggestedWords, pos);
+ final String debugInfo = Utils.getDebugInfo(suggestedWords, pos);
if (debugInfo != null) {
final TextView info = mInfos.get(pos);
info.setText(debugInfo);
@@ -466,7 +466,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
final TextView word = mWords.get(index);
word.setEnabled(true);
word.setTextColor(mColorAutoCorrect);
- final CharSequence text = suggestedWords.getWord(index);
+ final String text = suggestedWords.getWord(index);
word.setText(text);
word.setTextScaleX(1.0f);
word.setCompoundDrawables(null, null, null, null);
@@ -476,7 +476,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mMoreSuggestionsAvailable = false;
}
- public void layoutAddToDictionaryHint(final CharSequence word, final ViewGroup stripView,
+ public void layoutAddToDictionaryHint(final String word, final ViewGroup stripView,
final int stripWidth, final CharSequence hintText, final OnClickListener listener) {
final int width = stripWidth - mDividerWidth - mPadding * 2;
@@ -690,7 +690,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
&& mParams.isAddToDictionaryShowing(mSuggestionsStrip.getChildAt(0));
}
- public void showAddToDictionaryHint(final CharSequence word, final CharSequence hintText) {
+ public void showAddToDictionaryHint(final String word, final CharSequence hintText) {
clear();
mParams.layoutAddToDictionaryHint(word, mSuggestionsStrip, getWidth(), hintText, this);
}
@@ -723,7 +723,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@Override
public boolean onCustomRequest(final int requestCode) {
final int index = requestCode;
- final CharSequence word = mSuggestedWords.getWord(index);
+ final String word = mSuggestedWords.getWord(index);
mListener.pickSuggestionManually(index, word);
dismissMoreSuggestions();
return true;
@@ -871,7 +871,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
if (index >= mSuggestedWords.size())
return;
- final CharSequence word = mSuggestedWords.getWord(index);
+ final String word = mSuggestedWords.getWord(index);
mListener.pickSuggestionManually(index, word);
}
diff --git a/tests/src/com/android/inputmethod/latin/InputTestsBase.java b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
index eb5002059..70330509f 100644
--- a/tests/src/com/android/inputmethod/latin/InputTestsBase.java
+++ b/tests/src/com/android/inputmethod/latin/InputTestsBase.java
@@ -281,7 +281,7 @@ public class InputTestsBase extends ServiceTestCase {
waitForDictionaryToBeLoaded();
}
- protected void pickSuggestionManually(final int index, final CharSequence suggestion) {
+ protected void pickSuggestionManually(final int index, final String suggestion) {
mLatinIME.pickSuggestionManually(index, suggestion);
}
--
cgit v1.2.3-83-g751a
From 15f6d4ae34664ea3d92827a2c3003198c0bac70b Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Wed, 3 Oct 2012 17:36:45 +0900
Subject: Add @UsedForTesting and @ExternallyReferenced annotations
Bug: 7268357
Change-Id: I0b7e0c19f04af9ae30874d0a4c26ad81bc80be8c
---
java/proguard.flags | 69 +++-------------------
.../annotations/ExternallyReferenced.java | 24 ++++++++
.../inputmethod/annotations/UsedForTesting.java | 24 ++++++++
.../inputmethod/keyboard/KeyboardLayoutSet.java | 3 +-
.../inputmethod/keyboard/MainKeyboardView.java | 6 +-
.../inputmethod/keyboard/MoreKeysKeyboard.java | 3 +-
.../keyboard/internal/KeyboardBuilder.java | 3 +-
.../keyboard/internal/KeyboardTextsSet.java | 3 +-
.../keyboard/internal/TouchPositionCorrection.java | 3 +-
.../inputmethod/latin/BinaryDictionary.java | 3 +-
.../inputmethod/latin/ExpandableDictionary.java | 22 +------
.../android/inputmethod/latin/InputPointers.java | 8 ++-
.../com/android/inputmethod/latin/LatinIME.java | 11 ++--
.../src/com/android/inputmethod/latin/Suggest.java | 4 +-
.../inputmethod/latin/UserHistoryDictIOUtils.java | 7 ++-
.../inputmethod/latin/UserHistoryDictionary.java | 4 +-
.../latin/makedict/BinaryDictIOUtils.java | 6 ++
.../latin/makedict/BinaryDictInputOutput.java | 2 +
.../spellcheck/SpellCheckerProximityInfo.java | 3 +-
tools/dicttool/Android.mk | 6 +-
.../latin/makedict/BinaryDictInputOutputTest.java | 14 +----
tools/dicttool/tests/etc/test-dicttool.sh | 2 +-
.../keyboard/internal/KeyboardTextsSet.tmpl | 3 +-
23 files changed, 116 insertions(+), 117 deletions(-)
create mode 100644 java/src/com/android/inputmethod/annotations/ExternallyReferenced.java
create mode 100644 java/src/com/android/inputmethod/annotations/UsedForTesting.java
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/proguard.flags b/java/proguard.flags
index ac5b7df16..d65924f7c 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -1,64 +1,11 @@
--keep class com.android.inputmethod.latin.BinaryDictionary {
- int mDictLength;
- (...);
+# Keep classes and methods that have the @UsedForTesting annotation
+-keep @com.android.inputmethod.annotations.UsedForTesting class *
+-keepclassmembers class * {
+@com.android.inputmethod.annotations.UsedForTesting *;
}
--keep class com.android.inputmethod.keyboard.ProximityInfo {
- (com.android.inputmethod.keyboard.ProximityInfo);
+# Keep classes and methods that have the @ExternallyReferenced annotation
+-keep @com.android.inputmethod.annotations.ExternallyReferenced class *
+-keepclassmembers class * {
+@com.android.inputmethod.annotations.ExternallyReferenced *;
}
-
--keep class com.android.inputmethod.latin.Suggest {
- (...);
- com.android.inputmethod.latin.SuggestedWords getSuggestions(...);
-}
-
--keep class com.android.inputmethod.latin.AutoCorrection {
- java.lang.CharSequence getAutoCorrectionWord();
-}
-
--keep class com.android.inputmethod.latin.Utils {
- boolean equalsIgnoreCase(...);
-}
-
--keep class com.android.inputmethod.latin.InputPointers {
- *;
-}
-
--keep class com.android.inputmethod.latin.ResizableIntArray {
- *;
-}
-
--keep class com.android.inputmethod.latin.spellcheck.SpellCheckerSettingsFragment {
- *;
-}
-
--keep class com.android.inputmethod.keyboard.MainKeyboardView {
- # Keep getter/setter methods for ObjectAnimator
- int getLanguageOnSpacebarAnimAlpha();
- void setLanguageOnSpacebarAnimAlpha(int);
- int getAltCodeKeyWhileTypingAnimAlpha();
- void setAltCodeKeyWhileTypingAnimAlpha(int);
-}
-
--keep class com.android.inputmethod.keyboard.MoreKeysKeyboard$Builder$MoreKeysKeyboardParams {
- (...);
-}
-
--keepclasseswithmembernames class * {
- native ;
-}
-
--keep class com.android.inputmethod.research.ResearchLogger {
- void flush();
- void publishCurrentLogUnit(...);
-}
-
--keep class com.android.inputmethod.keyboard.KeyboardLayoutSet$Builder {
- void setTouchPositionCorrectionEnabled(...);
-}
-
-# The support library contains references to newer platform versions.
-# Don't warn about those in case this app is linking against an older
-# platform version. We know about them, and they are safe.
--dontwarn android.support.v4.**
--dontwarn android.support.v13.**
diff --git a/java/src/com/android/inputmethod/annotations/ExternallyReferenced.java b/java/src/com/android/inputmethod/annotations/ExternallyReferenced.java
new file mode 100644
index 000000000..ea5f12ce2
--- /dev/null
+++ b/java/src/com/android/inputmethod/annotations/ExternallyReferenced.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 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.annotations;
+
+/**
+ * Denotes that the class, method or field should not be eliminated by ProGuard,
+ * because it is externally referenced. (See proguard.flags)
+ */
+public @interface ExternallyReferenced {
+}
diff --git a/java/src/com/android/inputmethod/annotations/UsedForTesting.java b/java/src/com/android/inputmethod/annotations/UsedForTesting.java
new file mode 100644
index 000000000..2ada091e4
--- /dev/null
+++ b/java/src/com/android/inputmethod/annotations/UsedForTesting.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 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.annotations;
+
+/**
+ * Denotes that the class, method or field should not be eliminated by ProGuard,
+ * so that unit tests can access it. (See proguard.flags)
+ */
+public @interface UsedForTesting {
+}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index ee373e72f..4d5d7e14e 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -34,6 +34,7 @@ import android.util.Xml;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.EditorInfoCompatUtils;
import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
@@ -265,7 +266,7 @@ public final class KeyboardLayoutSet {
return this;
}
- // For test only
+ @UsedForTesting
public void disableTouchPositionCorrectionDataForTest() {
mParams.mDisableTouchPositionCorrectionDataForTest = true;
}
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 3e6f92c2a..5b6820fa6 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -41,6 +41,7 @@ import android.widget.PopupWindow;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
+import com.android.inputmethod.annotations.ExternallyReferenced;
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
@@ -417,20 +418,23 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
return animator;
}
- // Getter/setter methods for {@link ObjectAnimator}.
+ @ExternallyReferenced
public int getLanguageOnSpacebarAnimAlpha() {
return mLanguageOnSpacebarAnimAlpha;
}
+ @ExternallyReferenced
public void setLanguageOnSpacebarAnimAlpha(final int alpha) {
mLanguageOnSpacebarAnimAlpha = alpha;
invalidateKey(mSpaceKey);
}
+ @ExternallyReferenced
public int getAltCodeKeyWhileTypingAnimAlpha() {
return mAltCodeKeyWhileTypingAnimAlpha;
}
+ @ExternallyReferenced
public void setAltCodeKeyWhileTypingAnimAlpha(final int alpha) {
mAltCodeKeyWhileTypingAnimAlpha = alpha;
updateAltCodeKeyWhileTyping();
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index d7d4be40b..3826a39a4 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -20,6 +20,7 @@ import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.view.View;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
@@ -39,7 +40,7 @@ public final class MoreKeysKeyboard extends Keyboard {
return mDefaultKeyCoordX;
}
- /* package for test */
+ @UsedForTesting
static class MoreKeysKeyboardParams extends KeyboardParams {
public boolean mIsFixedOrder;
/* package */int mTopRowAdjustment;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index b314a3795..36342688e 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -27,6 +27,7 @@ import android.util.TypedValue;
import android.util.Xml;
import android.view.InflateException;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
@@ -177,7 +178,7 @@ public class KeyboardBuilder {
return this;
}
- // For test only
+ @UsedForTesting
public void disableTouchPositionCorrectionDataForTest() {
mParams.mTouchPositionCorrection.setEnabled(false);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 3b7c6ad7a..c3875acb5 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard.internal;
import android.content.Context;
import android.content.res.Resources;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.R;
@@ -64,7 +65,7 @@ public final class KeyboardTextsSet {
loadStringResourcesInternal(context, RESOURCE_NAMES, R.string.english_ime_name);
}
- /* package for test */
+ @UsedForTesting
void loadStringResourcesInternal(Context context, final String[] resourceNames,
int referenceId) {
final Resources res = context.getResources();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/TouchPositionCorrection.java b/java/src/com/android/inputmethod/keyboard/internal/TouchPositionCorrection.java
index d8950a713..d7a2b6f39 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/TouchPositionCorrection.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/TouchPositionCorrection.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.keyboard.internal;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.LatinImeLogger;
public final class TouchPositionCorrection {
@@ -66,7 +67,7 @@ public final class TouchPositionCorrection {
}
}
- // For test only
+ @UsedForTesting
public void setEnabled(final boolean enabled) {
mEnabled = enabled;
}
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 9c48aa1a4..8c005f0e6 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -81,7 +81,6 @@ public final class BinaryDictionary extends Dictionary {
/**
* Constructor for the binary dictionary. This is supposed to be called from the
* dictionary factory.
- * All implementations should pass null into flagArray, except for testing purposes.
* @param context the context to access the environment from.
* @param filename the name of the file to read through native code.
* @param offset the offset of the dictionary data within the file.
@@ -174,7 +173,7 @@ public final class BinaryDictionary extends Dictionary {
return suggestions;
}
- /* package for test */ boolean isValidDictionary() {
+ public boolean isValidDictionary() {
return mNativeDict != 0;
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index 8cdc2a0af..fdd0250a3 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -267,8 +267,7 @@ public class ExpandableDictionary extends Dictionary {
// This reloads the dictionary if required, and returns whether it's currently updating its
// contents or not.
- // @VisibleForTesting
- boolean reloadDictionaryIfRequired() {
+ private boolean reloadDictionaryIfRequired() {
synchronized (mUpdatingLock) {
// If we need to update, start off a background task
if (mRequiresReload) startDictionaryLoadingTaskLocked();
@@ -613,25 +612,6 @@ public class ExpandableDictionary extends Dictionary {
}
}
- /**
- * Used for testing purposes and in the spell checker
- * This function will wait for loading from database to be done
- */
- void waitForDictionaryLoading() {
- while (mUpdatingDictionary) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- //
- }
- }
- }
-
- protected final void blockingReloadDictionaryIfRequired() {
- reloadDictionaryIfRequired();
- waitForDictionaryLoading();
- }
-
// Local to reverseLookUp, but do not allocate each time.
private final char[] mLookedUpString = new char[BinaryDictionary.MAX_WORD_LENGTH];
diff --git a/java/src/com/android/inputmethod/latin/InputPointers.java b/java/src/com/android/inputmethod/latin/InputPointers.java
index 6b48aabb3..7dffd96dd 100644
--- a/java/src/com/android/inputmethod/latin/InputPointers.java
+++ b/java/src/com/android/inputmethod/latin/InputPointers.java
@@ -16,6 +16,8 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.annotations.UsedForTesting;
+
// TODO: This class is not thread-safe.
public final class InputPointers {
private final int mDefaultCapacity;
@@ -39,7 +41,8 @@ public final class InputPointers {
mTimes.add(index, time);
}
- public void addPointer(int x, int y, int pointerId, int time) {
+ @UsedForTesting
+ void addPointer(int x, int y, int pointerId, int time) {
mXCoordinates.add(x);
mYCoordinates.add(y);
mPointerIds.add(pointerId);
@@ -66,7 +69,8 @@ public final class InputPointers {
* @param startPos the starting index of the pointers in {@code src}.
* @param length the number of pointers to be appended.
*/
- public void append(InputPointers src, int startPos, int length) {
+ @UsedForTesting
+ void append(InputPointers src, int startPos, int length) {
if (length == 0) {
return;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 4cf6a5112..869ce7286 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -60,6 +60,7 @@ import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.CompatUtils;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
@@ -132,14 +133,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private View mKeyPreviewBackingView;
private View mSuggestionsContainer;
private SuggestionStripView mSuggestionStripView;
- /* package for tests */ Suggest mSuggest;
+ @UsedForTesting Suggest mSuggest;
private CompletionInfo[] mApplicationSpecifiedCompletions;
private ApplicationInfo mTargetApplicationInfo;
private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
- /* package for tests */ final KeyboardSwitcher mKeyboardSwitcher;
+ @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher;
private boolean mShouldSwitchToLastSubtype = true;
@@ -422,7 +423,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
// Has to be package-visible for unit tests
- /* package for test */
+ @UsedForTesting
void loadSettings() {
// Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
// is not guaranteed. It may even be called at the same time on a different thread.
@@ -1848,7 +1849,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// TODO: make this private
// Outside LatinIME, only used by the test suite.
- /* package for tests */
+ @UsedForTesting
boolean isShowingPunctuationList() {
if (mSuggestionStripView == null) return false;
return mCurrentSettings.mSuggestPuncList == mSuggestionStripView.getSuggestions();
@@ -2232,7 +2233,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// TODO: Make this private
// Outside LatinIME, only used by the {@link InputTestsBase} test suite.
- /* package for test */
+ @UsedForTesting
void loadKeyboard() {
// When the device locale is changed in SetupWizard etc., this method may get called via
// onConfigurationChanged before SoftInputWindow is shown.
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index f0e3b4ebd..fea7215ff 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin;
import android.content.Context;
import android.text.TextUtils;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -71,7 +72,8 @@ public final class Suggest {
mLocale = locale;
}
- /* package for test */ Suggest(final Context context, final File dictionary,
+ @UsedForTesting
+ Suggest(final Context context, final File dictionary,
final long startOffset, final long length, final Locale locale) {
final Dictionary mainDict = DictionaryFactory.createDictionaryForTest(context, dictionary,
startOffset, length /* useFullEditDistance */, false, locale);
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
index e39011145..787197755 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.makedict.BinaryDictIOUtils;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
@@ -129,7 +130,8 @@ public final class UserHistoryDictIOUtils {
/**
* Constructs a new FusionDictionary from BigramDictionaryInterface.
*/
- /* packages for test */ static FusionDictionary constructFusionDictionary(
+ @UsedForTesting
+ static FusionDictionary constructFusionDictionary(
final BigramDictionaryInterface dict, final UserHistoryDictionaryBigramList bigrams) {
final FusionDictionary fusionDict = new FusionDictionary(new Node(),
new FusionDictionary.DictionaryOptions(new HashMap(), false,
@@ -193,7 +195,8 @@ public final class UserHistoryDictIOUtils {
/**
* Adds all unigrams and bigrams in maps to OnAddWordListener.
*/
- /* package for test */ static void addWordsFromWordMap(final Map unigrams,
+ @UsedForTesting
+ static void addWordsFromWordMap(final Map unigrams,
final Map frequencies,
final Map> bigrams, final OnAddWordListener to) {
for (Map.Entry entry : unigrams.entrySet()) {
diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
index 3615fa1fb..639c9b915 100644
--- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java
@@ -21,6 +21,7 @@ import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.UserHistoryDictIOUtils.BigramDictionaryInterface;
@@ -75,7 +76,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
private final SharedPreferences mPrefs;
// Should always be false except when we use this class for test
- /* package for test */ boolean isTest = false;
+ @UsedForTesting boolean isTest = false;
private static final ConcurrentHashMap>
sLangDictCache = CollectionUtils.newConcurrentHashMap();
@@ -390,6 +391,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary {
}
}
+ @UsedForTesting
void forceAddWordForTest(final String word1, final String word2, final boolean isValid) {
mBigramListLock.lock();
try {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 40e089f3a..05f2d933c 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.makedict;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.CharEncoding;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface;
@@ -167,6 +168,7 @@ public final class BinaryDictIOUtils {
* @throws IOException
* @throws UnsupportedFormatException
*/
+ @UsedForTesting
public static int getTerminalPosition(final FusionDictionaryBufferInterface buffer,
final String word) throws IOException, UnsupportedFormatException {
if (word == null) return FormatSpec.NOT_VALID_WORD;
@@ -254,6 +256,7 @@ public final class BinaryDictIOUtils {
* @throws IOException
* @throws UnsupportedFormatException
*/
+ @UsedForTesting
public static void deleteWord(final FusionDictionaryBufferInterface buffer,
final String word) throws IOException, UnsupportedFormatException {
buffer.position(0);
@@ -706,6 +709,8 @@ public final class BinaryDictIOUtils {
* @throws UnsupportedFormatException
*/
// TODO: Support batch insertion.
+ // TODO: Remove @UsedForTesting once UserHistoryDictionary is implemented by BinaryDictionary.
+ @UsedForTesting
public static void insertWord(final FusionDictionaryBufferInterface buffer,
final OutputStream destination, final String word, final int frequency,
final ArrayList bigramStrings,
@@ -959,6 +964,7 @@ public final class BinaryDictIOUtils {
* @throws IOException
* @throws UnsupportedFormatException
*/
+ @UsedForTesting
public static CharGroupInfo findWordFromBuffer(final FusionDictionaryBufferInterface buffer,
final String word) throws IOException, UnsupportedFormatException {
int position = getTerminalPosition(buffer, word);
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 2d39094ff..277796dd2 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.makedict;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.makedict.FormatSpec.FileHeader;
import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup;
@@ -1651,6 +1652,7 @@ public final class BinaryDictInputOutput {
* @param dict an optional dictionary to add words to, or null.
* @return the created (or merged) dictionary.
*/
+ @UsedForTesting
public static FusionDictionary readDictionaryBinary(
final FusionDictionaryBufferInterface buffer, final FusionDictionary dict)
throws IOException, UnsupportedFormatException {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
index 11bb97031..6c0d79c2b 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.spellcheck;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Constants;
@@ -23,7 +24,7 @@ import com.android.inputmethod.latin.Constants;
import java.util.TreeMap;
public final class SpellCheckerProximityInfo {
- /* public for test */
+ @UsedForTesting
final public static int NUL = Constants.NOT_A_CODE;
// This must be the same as MAX_PROXIMITY_CHARS_SIZE else it will not work inside
diff --git a/tools/dicttool/Android.mk b/tools/dicttool/Android.mk
index 5bd836a01..159c1c160 100644
--- a/tools/dicttool/Android.mk
+++ b/tools/dicttool/Android.mk
@@ -16,14 +16,18 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LATINIME_CORE_SOURCE_DIRECTORY := ../../java/src/com/android/inputmethod/latin
+LATINIME_BASE_SOURCE_DIRECTORY := ../../java/src/com/android/inputmethod
+LATINIME_CORE_SOURCE_DIRECTORY := $(LATINIME_BASE_SOURCE_DIRECTORY)/latin
+LATINIME_ANNOTATIONS_SOURCE_DIRECTORY := $(LATINIME_BASE_SOURCE_DIRECTORY)/annotations
MAKEDICT_CORE_SOURCE_DIRECTORY := $(LATINIME_CORE_SOURCE_DIRECTORY)/makedict
LOCAL_MAIN_SRC_FILES := $(call all-java-files-under,$(MAKEDICT_CORE_SOURCE_DIRECTORY))
LOCAL_TOOL_SRC_FILES := $(call all-java-files-under,src)
+LOCAL_ANNOTATIONS_SRC_FILES := $(call all-java-files-under,$(LATINIME_ANNOTATIONS_SOURCE_DIRECTORY))
LOCAL_SRC_FILES := $(LOCAL_TOOL_SRC_FILES) \
$(filter-out $(addprefix %/, $(notdir $(LOCAL_TOOL_SRC_FILES))), $(LOCAL_MAIN_SRC_FILES)) \
$(call all-java-files-under,tests) \
+ $(LOCAL_ANNOTATIONS_SRC_FILES) \
$(LATINIME_CORE_SOURCE_DIRECTORY)/Constants.java
LOCAL_JAR_MANIFEST := etc/manifest.txt
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictInputOutputTest.java b/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictInputOutputTest.java
index 88589b815..096902879 100644
--- a/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictInputOutputTest.java
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/makedict/BinaryDictInputOutputTest.java
@@ -19,24 +19,15 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
+import junit.framework.TestCase;
+
import java.util.ArrayList;
import java.util.HashMap;
-import junit.framework.TestCase;
-
/**
* Unit tests for BinaryDictInputOutput.
*/
public class BinaryDictInputOutputTest extends TestCase {
-
- public void setUp() throws Exception {
- super.setUp();
- }
-
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
// Test the flattened array contains the expected number of nodes, and
// that it does not contain any duplicates.
public void testFlattenNodes() {
@@ -55,5 +46,4 @@ public class BinaryDictInputOutputTest extends TestCase {
assertFalse("Flattened array contained the same node twice", result.contains(n));
}
}
-
}
diff --git a/tools/dicttool/tests/etc/test-dicttool.sh b/tools/dicttool/tests/etc/test-dicttool.sh
index 8834611cd..1283be21a 100755
--- a/tools/dicttool/tests/etc/test-dicttool.sh
+++ b/tools/dicttool/tests/etc/test-dicttool.sh
@@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-java -classpath ${ANDROID_HOST_OUT}/framework/junit.jar:${ANDROID_HOST_OUT}/../common/obj/JAVA_LIBRARIES/dicttool_intermediates/classes junit.textui.TestRunner com.android.inputmethod.latin.makedict.BinaryDictInputOutputTest
+java -classpath ${ANDROID_HOST_OUT}/framework/junit.jar:${ANDROID_HOST_OUT}/framework/dicttool_aosp.jar junit.textui.TestRunner com.android.inputmethod.latin.makedict.BinaryDictInputOutputTest
diff --git a/tools/maketext/res/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.tmpl b/tools/maketext/res/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.tmpl
index 774094cd7..15aea9084 100644
--- a/tools/maketext/res/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.tmpl
+++ b/tools/maketext/res/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.tmpl
@@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard.internal;
import android.content.Context;
import android.content.res.Resources;
+import com.android.inputmethod.annotations.VisibleForTesting;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.R;
@@ -64,7 +65,7 @@ public final class KeyboardTextsSet {
loadStringResourcesInternal(context, RESOURCE_NAMES, R.string.english_ime_name);
}
- /* package for test */
+ @VisibleForTesting
void loadStringResourcesInternal(Context context, final String[] resourceNames,
int referenceId) {
final Resources res = context.getResources();
--
cgit v1.2.3-83-g751a
From f960eb186d63aa4f9fecd22f036fc8724d39d949 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Tue, 23 Oct 2012 11:30:39 +0900
Subject: Don't put spaces after characters that don't take one
Bug: 7393639
Change-Id: I1245a7b5077e554642838d6856ce269ca7f91988
---
java/src/com/android/inputmethod/latin/LatinIME.java | 6 +++++-
java/src/com/android/inputmethod/latin/SettingsValues.java | 2 ++
2 files changed, 7 insertions(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c1b1751f1..1ade3c422 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1431,8 +1431,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mSpaceState = SPACE_STATE_PHANTOM;
} else {
final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor();
+ // TODO: reverse this logic. We should have the means to determine whether a character
+ // should usually be followed by a space, and it should be more readable.
if (Constants.NOT_A_CODE != codePointBeforeCursor
- && !Character.isWhitespace(codePointBeforeCursor)) {
+ && !Character.isWhitespace(codePointBeforeCursor)
+ && !mCurrentSettings.isPhantomSpacePromotingSymbol(codePointBeforeCursor)
+ && !mCurrentSettings.isWeakSpaceStripper(codePointBeforeCursor)) {
mSpaceState = SPACE_STATE_PHANTOM;
}
}
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 1c5864bce..2a778aa0d 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -254,11 +254,13 @@ public final class SettingsValues {
return mSymbolsExcludedFromWordSeparators.contains(String.valueOf((char)code));
}
+ // TODO: use "Phantom" instead of "Weak" in this method name
public boolean isWeakSpaceStripper(final int code) {
// TODO: this does not work if the code does not fit in a char
return mWeakSpaceStrippers.contains(String.valueOf((char)code));
}
+ // TODO: use "Phantom" instead of "Weak" in this method name
public boolean isWeakSpaceSwapper(final int code) {
// TODO: this does not work if the code does not fit in a char
return mWeakSpaceSwappers.contains(String.valueOf((char)code));
--
cgit v1.2.3-83-g751a
From 9bb4eebf48f3e15bcdfe37d73f26693bd4eaf0f4 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 22 Oct 2012 17:00:39 +0900
Subject: Add reader and writer for the combined dict format.
This introduces a new textual format for the dictionary that combines
words, bigrams and shortcuts to avoid complexity. It is also extensible
to n-grams to fool-prof for the future, and easier to read than XML.
Bug: 7388540
Change-Id: I942bbad51bd0c905a5a54c278667563fd6dd66ec
---
.../latin/BinaryDictionaryFileDumper.java | 8 +-
.../latin/dicttool/CombinedInputOutput.java | 238 +++++++++++++++++++++
.../latin/dicttool/DictionaryMaker.java | 91 ++++++--
.../inputmethod/latin/dicttool/Dicttool.java | 1 +
4 files changed, 319 insertions(+), 19 deletions(-)
create mode 100644 tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index bed31a7d1..b0b65edb6 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -149,13 +149,7 @@ public final class BinaryDictionaryFileDumper {
final Uri.Builder wordListUriBuilder = getProviderUriBuilder(id);
final String finalFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
- String tempFileName;
- try {
- tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
- } catch (IOException e) {
- Log.e(TAG, "Can't open the temporary file", e);
- return null;
- }
+ final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
InputStream originalSourceStream = null;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
new file mode 100644
index 000000000..c17667536
--- /dev/null
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2012 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.latin.dicttool;
+
+import com.android.inputmethod.latin.makedict.FusionDictionary;
+import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.makedict.Word;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.TreeSet;
+
+/**
+ * Reads and writes combined format for a FusionDictionary.
+ *
+ * All functions in this class are static.
+ */
+public class CombinedInputOutput {
+
+ private static final String DICTIONARY_TAG = "dictionary";
+ private static final String BIGRAM_TAG = "bigram";
+ private static final String SHORTCUT_TAG = "shortcut";
+ private static final String FREQUENCY_TAG = "f";
+ private static final String WORD_TAG = "word";
+ private static final String NOT_A_WORD_TAG = "not_a_word";
+ private static final String WHITELIST_TAG = "whitelist";
+ private static final String OPTIONS_TAG = "options";
+ private static final String GERMAN_UMLAUT_PROCESSING_OPTION = "german_umlaut_processing";
+ private static final String FRENCH_LIGATURE_PROCESSING_OPTION = "french_ligature_processing";
+
+ /**
+ * Basic test to find out whether the file is in the combined format or not.
+ *
+ * Concretely this only tests the header line.
+ *
+ * @param filename The name of the file to test.
+ * @return true if the file is in the combined format, false otherwise
+ */
+ public static boolean isCombinedDictionary(final String filename) {
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(new File(filename)));
+ final String firstLine = reader.readLine();
+ return firstLine.matches("^" + DICTIONARY_TAG + "=[^:]+(:[^=]+=[^:]+)*");
+ } catch (FileNotFoundException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+
+ /**
+ * Reads a dictionary from a combined format file.
+ *
+ * This is the public method that will read a combined file and return the corresponding memory
+ * representation.
+ *
+ * @param source the file to read the data from.
+ * @return the in-memory representation of the dictionary.
+ */
+ public static FusionDictionary readDictionaryCombined(final InputStream source)
+ throws IOException {
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(source, "UTF-8"));
+ final String headerLine = reader.readLine();
+ final String header[] = headerLine.split(",");
+ final HashMap attributes = new HashMap();
+ for (String item : header) {
+ final String keyValue[] = item.split("=");
+ if (2 != keyValue.length) {
+ throw new RuntimeException("Wrong header format : " + headerLine);
+ }
+ attributes.put(keyValue[0], keyValue[1]);
+ }
+
+ final boolean processUmlauts =
+ GERMAN_UMLAUT_PROCESSING_OPTION.equals(attributes.get(OPTIONS_TAG));
+ final boolean processLigatures =
+ FRENCH_LIGATURE_PROCESSING_OPTION.equals(attributes.get(OPTIONS_TAG));
+ attributes.remove(OPTIONS_TAG);
+ final FusionDictionary dict = new FusionDictionary(new Node(), new DictionaryOptions(
+ attributes, processUmlauts, processLigatures));
+
+ String line;
+ String word = null;
+ int freq = 0;
+ boolean isNotAWord = false;
+ ArrayList bigrams = new ArrayList();
+ ArrayList shortcuts = new ArrayList();
+ while (null != (line = reader.readLine())) {
+ final String args[] = line.trim().split(",");
+ if (args[0].matches(WORD_TAG + "=.*")) {
+ if (null != word) {
+ dict.add(word, freq, shortcuts.isEmpty() ? null : shortcuts, isNotAWord);
+ for (WeightedString s : bigrams) {
+ dict.setBigram(word, s.mWord, s.mFrequency);
+ }
+ }
+ if (!shortcuts.isEmpty()) shortcuts = new ArrayList();
+ if (!bigrams.isEmpty()) bigrams = new ArrayList();
+ isNotAWord = false;
+ for (String param : args) {
+ final String params[] = param.split("=", 2);
+ if (2 != params.length) throw new RuntimeException("Wrong format : " + line);
+ if (WORD_TAG.equals(params[0])) {
+ word = params[1];
+ } else if (FREQUENCY_TAG.equals(params[0])) {
+ freq = Integer.parseInt(params[1]);
+ } else if (NOT_A_WORD_TAG.equals(params[0])) {
+ isNotAWord = "true".equals(params[1]);
+ }
+ }
+ } else if (args[0].matches(SHORTCUT_TAG + "=.*")) {
+ String shortcut = null;
+ int shortcutFreq = 0;
+ for (String param : args) {
+ final String params[] = param.split("=", 2);
+ if (2 != params.length) throw new RuntimeException("Wrong format : " + line);
+ if (SHORTCUT_TAG.equals(params[0])) {
+ shortcut = params[1];
+ } else if (FREQUENCY_TAG.equals(params[0])) {
+ shortcutFreq =
+ WHITELIST_TAG.equals(params[1]) ? 15 : Integer.parseInt(params[1]);
+ }
+ }
+ if (null != shortcut) {
+ shortcuts.add(new WeightedString(shortcut, shortcutFreq));
+ } else {
+ throw new RuntimeException("Wrong format : " + line);
+ }
+ } else if (args[0].matches(BIGRAM_TAG + "=.*")) {
+ String secondWordOfBigram = null;
+ int bigramFreq = 0;
+ for (String param : args) {
+ final String params[] = param.split("=", 2);
+ if (2 != params.length) throw new RuntimeException("Wrong format : " + line);
+ if (BIGRAM_TAG.equals(params[0])) {
+ secondWordOfBigram = params[1];
+ } else if (FREQUENCY_TAG.equals(params[0])) {
+ bigramFreq = Integer.parseInt(params[1]);
+ }
+ }
+ if (null != secondWordOfBigram) {
+ bigrams.add(new WeightedString(secondWordOfBigram, bigramFreq));
+ } else {
+ throw new RuntimeException("Wrong format : " + line);
+ }
+ }
+ }
+ if (null != word) {
+ dict.add(word, freq, shortcuts.isEmpty() ? null : shortcuts, isNotAWord);
+ for (WeightedString s : bigrams) {
+ dict.setBigram(word, s.mWord, s.mFrequency);
+ }
+ }
+
+ return dict;
+ }
+
+ /**
+ * Writes a dictionary to a combined file.
+ *
+ * @param destination a destination stream to write to.
+ * @param dict the dictionary to write.
+ */
+ public static void writeDictionaryCombined(Writer destination, FusionDictionary dict)
+ throws IOException {
+ final TreeSet set = new TreeSet();
+ for (Word word : dict) {
+ set.add(word); // This for ordering by frequency, then by asciibetic order
+ }
+ final HashMap options = dict.mOptions.mAttributes;
+ destination.write(DICTIONARY_TAG + "=");
+ if (options.containsKey(DICTIONARY_TAG)) {
+ destination.write(options.get(DICTIONARY_TAG));
+ options.remove(DICTIONARY_TAG);
+ }
+ if (dict.mOptions.mGermanUmlautProcessing) {
+ destination.write("," + OPTIONS_TAG + "=" + GERMAN_UMLAUT_PROCESSING_OPTION);
+ } else if (dict.mOptions.mFrenchLigatureProcessing) {
+ destination.write("," + OPTIONS_TAG + "=" + FRENCH_LIGATURE_PROCESSING_OPTION);
+ }
+ for (final String key : dict.mOptions.mAttributes.keySet()) {
+ final String value = dict.mOptions.mAttributes.get(key);
+ destination.write("," + key + "=" + value);
+ }
+ destination.write("\n");
+ for (Word word : set) {
+ destination.write("\t" + WORD_TAG + "=" + word.mWord + ","
+ + FREQUENCY_TAG + "=" + word.mFrequency
+ + (word.mIsNotAWord ? "," + NOT_A_WORD_TAG + "=true\n" : "\n"));
+ if (null != word.mShortcutTargets) {
+ for (WeightedString target : word.mShortcutTargets) {
+ destination.write("\t\t" + SHORTCUT_TAG + "=" + target.mWord + ","
+ + FREQUENCY_TAG + "=" + target.mFrequency + "\n");
+ }
+ }
+ if (null != word.mBigrams) {
+ for (WeightedString bigram : word.mBigrams) {
+ destination.write("\t\t" + BIGRAM_TAG + "=" + bigram.mWord + ","
+ + FREQUENCY_TAG + "=" + bigram.mFrequency + "\n");
+ }
+ }
+ }
+ destination.close();
+ }
+}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
index 2cdd83e96..561db7363 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/DictionaryMaker.java
@@ -52,13 +52,16 @@ public class DictionaryMaker {
private static final String OPTION_INPUT_SHORTCUT_XML = "-c";
private static final String OPTION_OUTPUT_BINARY = "-d";
private static final String OPTION_OUTPUT_XML = "-x";
+ private static final String OPTION_OUTPUT_COMBINED = "-o";
private static final String OPTION_HELP = "-h";
public final String mInputBinary;
+ public final String mInputCombined;
public final String mInputUnigramXml;
public final String mInputShortcutXml;
public final String mInputBigramXml;
public final String mOutputBinary;
public final String mOutputXml;
+ public final String mOutputCombined;
public final int mOutputBinaryFormatVersion;
private void checkIntegrity() throws IOException {
@@ -66,28 +69,38 @@ public class DictionaryMaker {
checkHasAtLeastOneOutput();
checkNotSameFile(mInputBinary, mOutputBinary);
checkNotSameFile(mInputBinary, mOutputXml);
+ checkNotSameFile(mInputCombined, mOutputBinary);
+ checkNotSameFile(mInputCombined, mOutputXml);
checkNotSameFile(mInputUnigramXml, mOutputBinary);
checkNotSameFile(mInputUnigramXml, mOutputXml);
+ checkNotSameFile(mInputUnigramXml, mOutputCombined);
checkNotSameFile(mInputShortcutXml, mOutputBinary);
checkNotSameFile(mInputShortcutXml, mOutputXml);
+ checkNotSameFile(mInputShortcutXml, mOutputCombined);
checkNotSameFile(mInputBigramXml, mOutputBinary);
checkNotSameFile(mInputBigramXml, mOutputXml);
+ checkNotSameFile(mInputBigramXml, mOutputCombined);
checkNotSameFile(mOutputBinary, mOutputXml);
+ checkNotSameFile(mOutputBinary, mOutputCombined);
+ checkNotSameFile(mOutputXml, mOutputCombined);
}
private void checkHasExactlyOneInput() {
- if (null == mInputUnigramXml && null == mInputBinary) {
+ if (null == mInputUnigramXml && null == mInputBinary && null == mInputCombined) {
throw new RuntimeException("No input file specified");
- } else if (null != mInputUnigramXml && null != mInputBinary) {
- throw new RuntimeException("Both input XML and binary specified");
- } else if (null != mInputBinary && null != mInputBigramXml) {
- throw new RuntimeException("Cannot specify a binary input and a separate bigram "
- + "file");
+ } else if ((null != mInputUnigramXml && null != mInputBinary)
+ || (null != mInputUnigramXml && null != mInputCombined)
+ || (null != mInputBinary && null != mInputCombined)) {
+ throw new RuntimeException("Several input files specified");
+ } else if ((null != mInputBinary || null != mInputCombined)
+ && (null != mInputBigramXml || null != mInputShortcutXml)) {
+ throw new RuntimeException("Separate bigrams/shortcut files are only supported"
+ + " with XML input (other formats include bigrams and shortcuts already)");
}
}
private void checkHasAtLeastOneOutput() {
- if (null == mOutputBinary && null == mOutputXml) {
+ if (null == mOutputBinary && null == mOutputXml && null == mOutputCombined) {
throw new RuntimeException("No output specified");
}
}
@@ -111,17 +124,16 @@ public class DictionaryMaker {
public static String getHelp() {
return "Usage: makedict "
+ "[-s [-b ] [-c ] "
+ + "| [-s ] [-d ] [-x ] "
+ + " [-o ]"
+ "[-1] [-2] [-3]\n"
+ "\n"
+ " Converts a source dictionary file to one or several outputs.\n"
+ " Source can be an XML file, with an optional XML bigrams file, or a\n"
+ " binary dictionary file.\n"
- + " Binary version 1 (Ice Cream Sandwich), 2 (Jelly Bean), 3 and XML outputs\n"
- + " are supported. All three can be output at the same time, but the same\n"
- + " output format cannot be specified several times. The behavior is\n"
- + " unspecified if the same file is specified for input and output, or for\n"
- + " several outputs.";
+ + " Binary version 1 (Ice Cream Sandwich), 2 (Jelly Bean), 3, XML and\n"
+ + " combined format outputs are supported.";
}
public Arguments(String[] argsArray) throws IOException {
@@ -130,11 +142,13 @@ public class DictionaryMaker {
displayHelp();
}
String inputBinary = null;
+ String inputCombined = null;
String inputUnigramXml = null;
String inputShortcutXml = null;
String inputBigramXml = null;
String outputBinary = null;
String outputXml = null;
+ String outputCombined = null;
int outputBinaryFormatVersion = 2; // the default version is 2.
while (!args.isEmpty()) {
@@ -160,6 +174,8 @@ public class DictionaryMaker {
if (OPTION_INPUT_SOURCE.equals(arg)) {
if (BinaryDictInputOutput.isBinaryDictionary(filename)) {
inputBinary = filename;
+ } else if (CombinedInputOutput.isCombinedDictionary(filename)) {
+ inputCombined = filename;
} else {
inputUnigramXml = filename;
}
@@ -171,6 +187,8 @@ public class DictionaryMaker {
outputBinary = filename;
} else if (OPTION_OUTPUT_XML.equals(arg)) {
outputXml = filename;
+ } else if (OPTION_OUTPUT_COMBINED.equals(arg)) {
+ outputCombined = filename;
} else {
throw new IllegalArgumentException("Unknown option : " + arg);
}
@@ -179,6 +197,8 @@ public class DictionaryMaker {
if (null == inputBinary && null == inputUnigramXml) {
if (BinaryDictInputOutput.isBinaryDictionary(arg)) {
inputBinary = arg;
+ } else if (CombinedInputOutput.isCombinedDictionary(arg)) {
+ inputCombined = arg;
} else {
inputUnigramXml = arg;
}
@@ -191,11 +211,13 @@ public class DictionaryMaker {
}
mInputBinary = inputBinary;
+ mInputCombined = inputCombined;
mInputUnigramXml = inputUnigramXml;
mInputShortcutXml = inputShortcutXml;
mInputBigramXml = inputBigramXml;
mOutputBinary = outputBinary;
mOutputXml = outputXml;
+ mOutputCombined = outputCombined;
mOutputBinaryFormatVersion = outputBinaryFormatVersion;
checkIntegrity();
}
@@ -220,6 +242,8 @@ public class DictionaryMaker {
SAXException, FileNotFoundException {
if (null != args.mInputBinary) {
return readBinaryFile(args.mInputBinary);
+ } else if (null != args.mInputCombined) {
+ return readCombinedFile(args.mInputCombined);
} else if (null != args.mInputUnigramXml) {
return readXmlFile(args.mInputUnigramXml, args.mInputShortcutXml, args.mInputBigramXml);
} else {
@@ -258,6 +282,32 @@ public class DictionaryMaker {
}
}
+ /**
+ * Read a dictionary from the name of a combined file.
+ *
+ * @param combinedFilename the name of the file in the combined format.
+ * @return the read dictionary.
+ * @throws FileNotFoundException if the file can't be found
+ * @throws IOException if the input file can't be read
+ */
+ private static FusionDictionary readCombinedFile(final String combinedFilename)
+ throws FileNotFoundException, IOException {
+ FileInputStream inStream = null;
+ try {
+ final File file = new File(combinedFilename);
+ inStream = new FileInputStream(file);
+ return CombinedInputOutput.readDictionaryCombined(inStream);
+ } finally {
+ if (null != inStream) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+
/**
* Read a dictionary from a unigram XML file, and optionally a bigram XML file.
*
@@ -299,6 +349,9 @@ public class DictionaryMaker {
if (null != args.mOutputXml) {
writeXmlDictionary(args.mOutputXml, dict);
}
+ if (null != args.mOutputCombined) {
+ writeCombinedDictionary(args.mOutputCombined, dict);
+ }
}
/**
@@ -332,4 +385,18 @@ public class DictionaryMaker {
XmlDictInputOutput.writeDictionaryXml(new BufferedWriter(new FileWriter(outputFilename)),
dict);
}
+
+ /**
+ * Write the dictionary in the combined format to the specified filename.
+ *
+ * @param outputFilename the name of the file to write to.
+ * @param dict the dictionary to write.
+ * @throws FileNotFoundException if the output file can't be created.
+ * @throws IOException if the output file can't be written to.
+ */
+ private static void writeCombinedDictionary(final String outputFilename,
+ final FusionDictionary dict) throws FileNotFoundException, IOException {
+ CombinedInputOutput.writeDictionaryCombined(
+ new BufferedWriter(new FileWriter(outputFilename)), dict);
+ }
}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Dicttool.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Dicttool.java
index bf417fb5a..75ce104e0 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Dicttool.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Dicttool.java
@@ -80,6 +80,7 @@ public class Dicttool {
} catch (Exception e) {
System.out.println("Exception while processing command "
+ command.getClass().getSimpleName() + " : " + e);
+ e.printStackTrace();
return;
}
}
--
cgit v1.2.3-83-g751a
From 1e0cc86b6f77e69273f41f6f291af25968a790f6 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Tue, 23 Oct 2012 15:34:03 +0900
Subject: Fix the build.
It seems this change snuck out from a previous version.
Change-Id: I9c33d51273732b1d55bfd60f0957184c86fa88ab
---
.../com/android/inputmethod/latin/BinaryDictionaryFileDumper.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index b0b65edb6..bed31a7d1 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -149,7 +149,13 @@ public final class BinaryDictionaryFileDumper {
final Uri.Builder wordListUriBuilder = getProviderUriBuilder(id);
final String finalFileName = BinaryDictionaryGetter.getCacheFileName(id, locale, context);
- final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
+ String tempFileName;
+ try {
+ tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
+ } catch (IOException e) {
+ Log.e(TAG, "Can't open the temporary file", e);
+ return null;
+ }
for (int mode = MODE_MIN; mode <= MODE_MAX; ++mode) {
InputStream originalSourceStream = null;
--
cgit v1.2.3-83-g751a
From c59c7419878d91852420bcc6663e7dc6aaf446fd Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Tue, 23 Oct 2012 12:07:57 +0900
Subject: Return the correct bigram frequency
The "correct" bigram frequency is now returned by the reading
code. However, as the binary format represents the frequency
in a lossy manner, the frequency is not guaranteed to be the
exact same as the one in the source text format - only a close
enough value. It is however the exact same value seen by the
native code.
Bug: 7395653
Change-Id: I49199ef18901c671189912b3550623e9643baedd
---
.../latin/makedict/BinaryDictInputOutput.java | 33 ++++++++++++++--------
1 file changed, 21 insertions(+), 12 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 277796dd2..da5236974 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -1374,7 +1374,8 @@ public final class BinaryDictInputOutput {
// of this method. Since it performs direct, unbuffered random access to the file and
// may be called hundreds of thousands of times, the resulting performance is not
// reasonable without some kind of cache. Thus:
- private static TreeMap wordCache = new TreeMap();
+ private static TreeMap wordCache =
+ new TreeMap();
/**
* Finds, as a string, the word at the address passed as an argument.
*
@@ -1382,15 +1383,15 @@ public final class BinaryDictInputOutput {
* @param headerSize the size of the header.
* @param address the address to seek.
* @param formatOptions file format options.
- * @return the word, as a string.
+ * @return the word with its frequency, as a weighted string.
*/
- /* packages for tests */ static String getWordAtAddress(
+ /* package for tests */ static WeightedString getWordAtAddress(
final FusionDictionaryBufferInterface buffer, final int headerSize, final int address,
final FormatOptions formatOptions) {
- final String cachedString = wordCache.get(address);
+ final WeightedString cachedString = wordCache.get(address);
if (null != cachedString) return cachedString;
- final String result;
+ final WeightedString result;
final int originalPointer = buffer.position();
buffer.position(address);
@@ -1406,14 +1407,17 @@ public final class BinaryDictInputOutput {
return result;
}
+ // TODO: static!? This will behave erratically when used in multi-threaded code.
+ // We need to fix this
private static int[] sGetWordBuffer = new int[FormatSpec.MAX_WORD_LENGTH];
- private static String getWordAtAddressWithParentAddress(
+ private static WeightedString getWordAtAddressWithParentAddress(
final FusionDictionaryBufferInterface buffer, final int headerSize, final int address,
final FormatOptions options) {
final StringBuilder builder = new StringBuilder();
int currentAddress = address;
int index = FormatSpec.MAX_WORD_LENGTH - 1;
+ int frequency = Integer.MIN_VALUE;
// the length of the path from the root to the leaf is limited by MAX_WORD_LENGTH
for (int count = 0; count < FormatSpec.MAX_WORD_LENGTH; ++count) {
CharGroupInfo currentInfo;
@@ -1428,6 +1432,7 @@ public final class BinaryDictInputOutput {
MakedictLog.d("Too many jumps - probably a bug");
}
} while (isMovedGroup(currentInfo.mFlags, options));
+ if (Integer.MIN_VALUE == frequency) frequency = currentInfo.mFrequency;
for (int i = 0; i < currentInfo.mCharacters.length; ++i) {
sGetWordBuffer[index--] =
currentInfo.mCharacters[currentInfo.mCharacters.length - i - 1];
@@ -1436,17 +1441,19 @@ public final class BinaryDictInputOutput {
currentAddress = currentInfo.mParentAddress + currentInfo.mOriginalAddress;
}
- return new String(sGetWordBuffer, index + 1, FormatSpec.MAX_WORD_LENGTH - index - 1);
+ return new WeightedString(
+ new String(sGetWordBuffer, index + 1, FormatSpec.MAX_WORD_LENGTH - index - 1),
+ frequency);
}
- private static String getWordAtAddressWithoutParentAddress(
+ private static WeightedString getWordAtAddressWithoutParentAddress(
final FusionDictionaryBufferInterface buffer, final int headerSize, final int address,
final FormatOptions options) {
buffer.position(headerSize);
final int count = readCharGroupCount(buffer);
int groupOffset = getGroupCountSize(count);
final StringBuilder builder = new StringBuilder();
- String result = null;
+ WeightedString result = null;
CharGroupInfo last = null;
for (int i = count - 1; i >= 0; --i) {
@@ -1454,7 +1461,7 @@ public final class BinaryDictInputOutput {
groupOffset = info.mEndAddress;
if (info.mOriginalAddress == address) {
builder.append(new String(info.mCharacters, 0, info.mCharacters.length));
- result = builder.toString();
+ result = new WeightedString(builder.toString(), info.mFrequency);
break; // and return
}
if (hasChildrenAddress(info.mChildrenAddress)) {
@@ -1515,9 +1522,11 @@ public final class BinaryDictInputOutput {
if (null != info.mBigrams) {
bigrams = new ArrayList();
for (PendingAttribute bigram : info.mBigrams) {
- final String word = getWordAtAddress(
+ final WeightedString word = getWordAtAddress(
buffer, headerSize, bigram.mAddress, options);
- bigrams.add(new WeightedString(word, bigram.mFrequency));
+ final int reconstructedFrequency =
+ reconstructBigramFrequency(word.mFrequency, bigram.mFrequency);
+ bigrams.add(new WeightedString(word.mWord, reconstructedFrequency));
}
}
if (hasChildrenAddress(info.mChildrenAddress)) {
--
cgit v1.2.3-83-g751a
From ddb0bcc051c1e9f2706f3702f0bb3135e4352f7b Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Wed, 24 Oct 2012 13:24:59 +0900
Subject: Fix a bug where a bigram would be ignored
Bug: 7403386
Change-Id: I89f495d07f7059a9f1ccd97d487c2f2657a8ebd2
---
java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java | 4 ++++
1 file changed, 4 insertions(+)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 6f1faa192..7fd13d78b 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -358,6 +358,10 @@ public final class FusionDictionary implements Iterable {
if (charGroup2 == null) {
add(getCodePoints(word2), 0, null, false /* isNotAWord */,
false /* isBlacklistEntry */);
+ // The chargroup for the first word may have moved by the above insertion,
+ // if word1 and word2 share a common stem that happens not to have been
+ // a cutting point until now. In this case, we need to refresh charGroup.
+ charGroup = findWordInTree(mRoot, word1);
}
charGroup.addBigram(word2, frequency);
} else {
--
cgit v1.2.3-83-g751a
From b3c98901c5fc1460b54cdf27d74405f27c88e74b Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Tue, 23 Oct 2012 17:14:12 +0900
Subject: Add auto detection and decoding of dictionary files. (A2)
Bug: 7388852
Change-Id: I25e755fc15f5b383acc046f668e9681efa4f0c2f
---
.../latin/makedict/BinaryDictInputOutput.java | 11 ++-
.../latin/makedict/FusionDictionary.java | 6 ++
.../latin/dicttool/BinaryDictOffdeviceUtils.java | 82 ++++++++++++++--
.../inputmethod/latin/dicttool/Compress.java | 14 +--
.../dicttool/BinaryDictOffdeviceUtilsTests.java | 106 +++++++++++++++++++++
tools/dicttool/tests/etc/test-dicttool.sh | 1 +
6 files changed, 206 insertions(+), 14 deletions(-)
create mode 100644 tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index da5236974..031306e1d 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -1698,6 +1698,14 @@ public final class BinaryDictInputOutput {
return newDict;
}
+ /**
+ * Helper method to pass a file name instead of a File object to isBinaryDictionary.
+ */
+ public static boolean isBinaryDictionary(final String filename) {
+ final File file = new File(filename);
+ return isBinaryDictionary(file);
+ }
+
/**
* Basic test to find out whether the file is a binary dictionary or not.
*
@@ -1706,10 +1714,9 @@ public final class BinaryDictInputOutput {
* @param filename The name of the file to test.
* @return true if it's a binary dictionary, false otherwise
*/
- public static boolean isBinaryDictionary(final String filename) {
+ public static boolean isBinaryDictionary(final File file) {
FileInputStream inStream = null;
try {
- final File file = new File(filename);
inStream = new FileInputStream(file);
final ByteBuffer buffer = inStream.getChannel().map(
FileChannel.MapMode.READ_ONLY, 0, file.length());
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 7fd13d78b..44537986b 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.makedict;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
import java.util.ArrayList;
@@ -141,6 +142,11 @@ public final class FusionDictionary implements Iterable {
return NOT_A_TERMINAL != mFrequency;
}
+ @UsedForTesting
+ public int getFrequency() {
+ return mFrequency;
+ }
+
public boolean hasSeveralChars() {
assert(mChars.length > 0);
return 1 < mChars.length;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
index 83c5d9ac6..9dcd7eb42 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
@@ -16,19 +16,42 @@
package com.android.inputmethod.latin.dicttool;
+import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
+
+import java.io.File;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
/**
-* Class grouping utilities for offline dictionary making.
-*
-* Those should not be used on-device, essentially because they are quite
-* liberal about I/O and performance.
-*/
-public class BinaryDictOffdeviceUtils {
+ * Class grouping utilities for offline dictionary making.
+ *
+ * Those should not be used on-device, essentially because they are quite
+ * liberal about I/O and performance.
+ */
+public final class BinaryDictOffdeviceUtils {
+ // Prefix and suffix are arbitrary, the values do not really matter
+ private final static String PREFIX = "dicttool";
+ private final static String SUFFIX = ".tmp";
+
+ public final static String COMPRESSION = "compression";
+
+ public static class DecoderChainSpec {
+ ArrayList mDecoderSpec = new ArrayList();
+ File mFile;
+ public DecoderChainSpec addStep(final String stepDescription) {
+ mDecoderSpec.add(stepDescription);
+ return this;
+ }
+ }
+
public static void copy(final InputStream input, final OutputStream output) throws IOException {
final byte[] buffer = new byte[1000];
final BufferedInputStream in = new BufferedInputStream(input);
@@ -38,4 +61,51 @@ public class BinaryDictOffdeviceUtils {
in.close();
out.close();
}
+
+ /**
+ * Returns a decrypted/uncompressed binary dictionary.
+ *
+ * This will decrypt/uncompress any number of times as necessary until it finds the binary
+ * dictionary signature, and copy the decoded file to a temporary place.
+ * If this is not a binary dictionary, the method returns null.
+ */
+ public static DecoderChainSpec getRawBinaryDictionaryOrNull(final File src) {
+ return getRawBinaryDictionaryOrNullInternal(new DecoderChainSpec(), src);
+ }
+
+ private static DecoderChainSpec getRawBinaryDictionaryOrNullInternal(
+ final DecoderChainSpec spec, final File src) {
+ // TODO: arrange for the intermediary files to be deleted
+ if (BinaryDictInputOutput.isBinaryDictionary(src)) {
+ spec.mFile = src;
+ return spec;
+ }
+ // It's not a raw dictionary - try to see if it's compressed.
+ final File uncompressedFile = tryGetUncompressedFile(src);
+ if (null != uncompressedFile) {
+ final DecoderChainSpec newSpec =
+ getRawBinaryDictionaryOrNullInternal(spec, uncompressedFile);
+ if (null == newSpec) return null;
+ return newSpec.addStep(COMPRESSION);
+ }
+ return null;
+ }
+
+ /* Try to uncompress the file passed as an argument.
+ *
+ * If the file can be uncompressed, the uncompressed version is returned. Otherwise, null
+ * is returned.
+ */
+ private static File tryGetUncompressedFile(final File src) {
+ try {
+ final File dst = File.createTempFile(PREFIX, SUFFIX);
+ final FileOutputStream dstStream = new FileOutputStream(dst);
+ copy(Compress.getUncompressedStream(new BufferedInputStream(new FileInputStream(src))),
+ new BufferedOutputStream(dstStream)); // #copy() closes the streams
+ return dst;
+ } catch (IOException e) {
+ // Could not uncompress the file: presumably the file is simply not a compressed file
+ return null;
+ }
+ }
}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Compress.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Compress.java
index 49e90ada2..072de5c01 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Compress.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Compress.java
@@ -16,6 +16,8 @@
package com.android.inputmethod.latin.dicttool;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -27,12 +29,12 @@ import java.util.zip.GZIPOutputStream;
public class Compress {
- private static OutputStream getCompressedStream(final OutputStream out)
+ public static OutputStream getCompressedStream(final OutputStream out)
throws java.io.IOException {
return new GZIPOutputStream(out);
}
- private static InputStream getUncompressedStream(final InputStream in) throws IOException {
+ public static InputStream getUncompressedStream(final InputStream in) throws IOException {
return new GZIPInputStream(in);
}
@@ -55,9 +57,9 @@ public class Compress {
final String inFilename = mArgs.length >= 1 ? mArgs[0] : STDIN_OR_STDOUT;
final String outFilename = mArgs.length >= 2 ? mArgs[1] : STDIN_OR_STDOUT;
final InputStream input = inFilename.equals(STDIN_OR_STDOUT) ? System.in
- : new FileInputStream(new File(inFilename));
+ : new BufferedInputStream(new FileInputStream(new File(inFilename)));
final OutputStream output = outFilename.equals(STDIN_OR_STDOUT) ? System.out
- : new FileOutputStream(new File(outFilename));
+ : new BufferedOutputStream(new FileOutputStream(new File(outFilename)));
BinaryDictOffdeviceUtils.copy(input, new GZIPOutputStream(output));
}
}
@@ -81,9 +83,9 @@ public class Compress {
final String inFilename = mArgs.length >= 1 ? mArgs[0] : STDIN_OR_STDOUT;
final String outFilename = mArgs.length >= 2 ? mArgs[1] : STDIN_OR_STDOUT;
final InputStream input = inFilename.equals(STDIN_OR_STDOUT) ? System.in
- : new FileInputStream(new File(inFilename));
+ : new BufferedInputStream(new FileInputStream(new File(inFilename)));
final OutputStream output = outFilename.equals(STDIN_OR_STDOUT) ? System.out
- : new FileOutputStream(new File(outFilename));
+ : new BufferedOutputStream(new FileOutputStream(new File(outFilename)));
BinaryDictOffdeviceUtils.copy(new GZIPInputStream(input), output);
}
}
diff --git a/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
new file mode 100644
index 000000000..7a686e556
--- /dev/null
+++ b/tools/dicttool/tests/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtilsTests.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2012 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.latin.dicttool;
+
+import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
+import com.android.inputmethod.latin.makedict.FormatSpec.FormatOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary;
+import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
+import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
+import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.BufferedOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Unit tests for BinaryDictOffdeviceUtilsTests
+ */
+public class BinaryDictOffdeviceUtilsTests extends TestCase {
+ private static final int TEST_FREQ = 37; // Some arbitrary value unlikely to happen by chance
+
+ public void testGetRawDictWorks() throws IOException, UnsupportedFormatException {
+ // Create a thrice-compressed dictionary file.
+ final FusionDictionary dict = new FusionDictionary(new Node(),
+ new DictionaryOptions(new HashMap(),
+ false /* germanUmlautProcessing */, false /* frenchLigatureProcessing */));
+ dict.add("foo", TEST_FREQ, null, false /* isNotAWord */);
+ dict.add("fta", 1, null, false /* isNotAWord */);
+ dict.add("ftb", 1, null, false /* isNotAWord */);
+ dict.add("bar", 1, null, false /* isNotAWord */);
+ dict.add("fool", 1, null, false /* isNotAWord */);
+
+ final File dst = File.createTempFile("testGetRawDict", ".tmp");
+ final OutputStream out = Compress.getCompressedStream(
+ Compress.getCompressedStream(
+ Compress.getCompressedStream(
+ new BufferedOutputStream(new FileOutputStream(dst)))));
+
+ BinaryDictInputOutput.writeDictionaryBinary(out, dict, new FormatOptions(2, false));
+
+ // Test for an actually compressed dictionary and its contents
+ final BinaryDictOffdeviceUtils.DecoderChainSpec decodeSpec =
+ BinaryDictOffdeviceUtils.getRawBinaryDictionaryOrNull(dst);
+ for (final String step : decodeSpec.mDecoderSpec) {
+ assertEquals("Wrong decode spec", BinaryDictOffdeviceUtils.COMPRESSION, step);
+ }
+ assertEquals("Wrong decode spec", 3, decodeSpec.mDecoderSpec.size());
+ final FileInputStream inStream = new FileInputStream(decodeSpec.mFile);
+ final ByteBuffer buffer = inStream.getChannel().map(
+ FileChannel.MapMode.READ_ONLY, 0, decodeSpec.mFile.length());
+ final FusionDictionary resultDict = BinaryDictInputOutput.readDictionaryBinary(
+ new BinaryDictInputOutput.ByteBufferWrapper(buffer),
+ null /* dict : an optional dictionary to add words to, or null */);
+ assertEquals("Dictionary can't be read back correctly",
+ resultDict.findWordInTree(resultDict.mRoot, "foo").getFrequency(), TEST_FREQ);
+ }
+
+ public void testGetRawDictFails() throws IOException {
+ // Randomly create some 4k file containing garbage
+ final File dst = File.createTempFile("testGetRawDict", ".tmp");
+ final OutputStream out = new BufferedOutputStream(new FileOutputStream(dst));
+ for (int i = 0; i < 1024; ++i) {
+ out.write(0x12345678);
+ }
+ out.close();
+
+ // Test that a random data file actually fails
+ assertNull("Wrongly identified data file",
+ BinaryDictOffdeviceUtils.getRawBinaryDictionaryOrNull(dst));
+
+ final File gzDst = File.createTempFile("testGetRawDict", ".tmp");
+ final OutputStream gzOut =
+ Compress.getCompressedStream(new BufferedOutputStream(new FileOutputStream(gzDst)));
+ for (int i = 0; i < 1024; ++i) {
+ gzOut.write(0x12345678);
+ }
+ gzOut.close();
+
+ // Test that a compressed random data file actually fails
+ assertNull("Wrongly identified data file",
+ BinaryDictOffdeviceUtils.getRawBinaryDictionaryOrNull(gzDst));
+ }
+}
diff --git a/tools/dicttool/tests/etc/test-dicttool.sh b/tools/dicttool/tests/etc/test-dicttool.sh
index 1283be21a..0f3ed6d62 100755
--- a/tools/dicttool/tests/etc/test-dicttool.sh
+++ b/tools/dicttool/tests/etc/test-dicttool.sh
@@ -14,3 +14,4 @@
# limitations under the License.
java -classpath ${ANDROID_HOST_OUT}/framework/junit.jar:${ANDROID_HOST_OUT}/framework/dicttool_aosp.jar junit.textui.TestRunner com.android.inputmethod.latin.makedict.BinaryDictInputOutputTest
+java -classpath ${ANDROID_HOST_OUT}/framework/junit.jar:${ANDROID_HOST_OUT}/framework/dicttool_aosp.jar junit.textui.TestRunner com.android.inputmethod.latin.dicttool.BinaryDictOffdeviceUtilsTests
--
cgit v1.2.3-83-g751a
From 47cac57e4593f47e753410e4199e84e458d6de6f Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Thu, 25 Oct 2012 18:15:42 +0900
Subject: Finish up the "info" command in dicttool. (A6)
Bug: 7388857
Change-Id: I704f12a6be76ce1644ec5e8dd3b667f112e9c04a
---
.../inputmethod/latin/makedict/FormatSpec.java | 2 ++
.../latin/makedict/FusionDictionary.java | 36 +++++++++++++++++++--
.../latin/dicttool/CombinedInputOutput.java | 6 ++--
.../android/inputmethod/latin/dicttool/Info.java | 37 ++++++++++++++++++++--
4 files changed, 75 insertions(+), 6 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index e88a4aebf..705f66414 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -224,6 +224,8 @@ public final class FormatSpec {
static final int MAX_TERMINAL_FREQUENCY = 255;
static final int MAX_BIGRAM_FREQUENCY = 15;
+ public static final int SHORTCUT_WHITELIST_FREQUENCY = 15;
+
// This option needs to be the same numeric value as the one in binary_format.h.
static final int NOT_VALID_WORD = -99;
static final int SIGNED_CHILDREN_ADDRESS_SIZE = 3;
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 44537986b..4abed9f7f 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -22,6 +22,7 @@ import com.android.inputmethod.latin.Constants;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@@ -255,8 +256,6 @@ public final class FusionDictionary implements Iterable {
/**
* Options global to the dictionary.
- *
- * There are no options at the moment, so this class is empty.
*/
public static final class DictionaryOptions {
public final boolean mGermanUmlautProcessing;
@@ -268,6 +267,39 @@ public final class FusionDictionary implements Iterable {
mGermanUmlautProcessing = germanUmlautProcessing;
mFrenchLigatureProcessing = frenchLigatureProcessing;
}
+ @Override
+ public String toString() { // Convenience method
+ return toString(0);
+ }
+ public String toString(final int indentCount) {
+ final StringBuilder indent = new StringBuilder();
+ for (int i = 0; i < indentCount; ++i) {
+ indent.append(" ");
+ }
+ final StringBuilder s = new StringBuilder();
+ for (final String optionKey : mAttributes.keySet()) {
+ s.append(indent);
+ s.append(optionKey);
+ s.append(" = ");
+ if ("date".equals(optionKey)) {
+ // Date needs a number of milliseconds, but the dictionary contains seconds
+ s.append(new Date(
+ 1000 * Long.parseLong(mAttributes.get(optionKey))).toString());
+ } else {
+ s.append(mAttributes.get(optionKey));
+ }
+ s.append("\n");
+ }
+ if (mGermanUmlautProcessing) {
+ s.append(indent);
+ s.append("Needs German umlaut processing\n");
+ }
+ if (mFrenchLigatureProcessing) {
+ s.append(indent);
+ s.append("Needs French ligature processing\n");
+ }
+ return s.toString();
+ }
}
public final DictionaryOptions mOptions;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
index c17667536..cd04d18bb 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/CombinedInputOutput.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.dicttool;
+import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.FusionDictionary.DictionaryOptions;
import com.android.inputmethod.latin.makedict.FusionDictionary.Node;
@@ -150,8 +151,9 @@ public class CombinedInputOutput {
if (SHORTCUT_TAG.equals(params[0])) {
shortcut = params[1];
} else if (FREQUENCY_TAG.equals(params[0])) {
- shortcutFreq =
- WHITELIST_TAG.equals(params[1]) ? 15 : Integer.parseInt(params[1]);
+ shortcutFreq = WHITELIST_TAG.equals(params[1])
+ ? FormatSpec.SHORTCUT_WHITELIST_FREQUENCY
+ : Integer.parseInt(params[1]);
}
}
if (null != shortcut) {
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
index bafde627d..be4b2b881 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
@@ -18,8 +18,11 @@ package com.android.inputmethod.latin.dicttool;
import com.android.inputmethod.latin.dicttool.BinaryDictOffdeviceUtils.DecoderChainSpec;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
+import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FusionDictionary;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
+import com.android.inputmethod.latin.makedict.Word;
import org.xml.sax.SAXException;
@@ -38,8 +41,9 @@ public class Info extends Dicttool.Command {
public Info() {
}
+ @Override
public String getHelp() {
- return "info : prints various information about a dictionary file";
+ return COMMAND + ": prints various information about a dictionary file";
}
private static void crash(final String filename, final Exception e) {
@@ -72,6 +76,7 @@ public class Info extends Dicttool.Command {
FileChannel.MapMode.READ_ONLY, 0, decodedSpec.mFile.length());
System.out.println("Format : Binary dictionary format");
System.out.println("Packaging : " + decodedSpec.describeChain());
+ System.out.println("Uncompressed size : " + decodedSpec.mFile.length());
return BinaryDictInputOutput.readDictionaryBinary(
new BinaryDictInputOutput.ByteBufferWrapper(buffer), null);
}
@@ -87,12 +92,40 @@ public class Info extends Dicttool.Command {
return null;
}
+ private static void showInfo(final FusionDictionary dict) {
+ System.out.println("Header attributes :");
+ System.out.print(dict.mOptions.toString(2));
+ int wordCount = 0;
+ int bigramCount = 0;
+ int shortcutCount = 0;
+ int whitelistCount = 0;
+ for (final Word w : dict) {
+ ++wordCount;
+ if (null != w.mBigrams) {
+ bigramCount += w.mBigrams.size();
+ }
+ if (null != w.mShortcutTargets) {
+ shortcutCount += w.mShortcutTargets.size();
+ for (WeightedString shortcutTarget : w.mShortcutTargets) {
+ if (FormatSpec.SHORTCUT_WHITELIST_FREQUENCY == shortcutTarget.mFrequency) {
+ ++whitelistCount;
+ }
+ }
+ }
+ }
+ System.out.println("Words in the dictionary : " + wordCount);
+ System.out.println("Bigram count : " + bigramCount);
+ System.out.println("Shortcuts : " + shortcutCount + " (out of which " + whitelistCount
+ + " whitelist entries)");
+ }
+
+ @Override
public void run() {
- // TODO: implement this
if (mArgs.length < 1) {
throw new RuntimeException("Not enough arguments for command " + COMMAND);
}
final String filename = mArgs[0];
final FusionDictionary dict = getDictionary(filename);
+ showInfo(dict);
}
}
--
cgit v1.2.3-83-g751a
From 60dea36dafc4a567b948b5175bcca776b08fdfad Mon Sep 17 00:00:00 2001
From: Satoshi Kataoka
Date: Thu, 25 Oct 2012 14:48:12 +0900
Subject: Assuming that NO_EXTRACT_UI mode is NO_FULSCREEN
Bug: 7393485
Bug: 7272829
Change-Id: I873e8d99486c734e76484526631a90fc55e91c86
---
java/src/com/android/inputmethod/latin/LatinIME.java | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1ade3c422..8ac0cd4ca 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1063,7 +1063,16 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Reread resource value here, because this method is called by framework anytime as needed.
final boolean isFullscreenModeAllowed =
mCurrentSettings.isFullscreenModeAllowed(getResources());
- return super.onEvaluateFullscreenMode() && isFullscreenModeAllowed;
+ if (super.onEvaluateFullscreenMode() && isFullscreenModeAllowed) {
+ // TODO: Remove this hack. Actually we should not really assume NO_EXTRACT_UI
+ // implies NO_FULLSCREEN. However, the framework mistakenly does. i.e. NO_EXTRACT_UI
+ // without NO_FULLSCREEN doesn't work as expected. Because of this we need this
+ // hack for now. Let's get rid of this once the framework gets fixed.
+ final EditorInfo ei = getCurrentInputEditorInfo();
+ return !(ei != null && ((ei.imeOptions & EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0));
+ } else {
+ return false;
+ }
}
@Override
--
cgit v1.2.3-83-g751a
From a23e3330798a3ade6d2f4f5a94b71746feb1b948 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 29 Oct 2012 11:09:30 +0900
Subject: Implement the word-level diff (A9)
Bug: 7388857
Change-Id: I4c4560d4f4b579936a44cdf409a4c27300b65610
---
.../latin/makedict/FusionDictionary.java | 25 +++++-
.../android/inputmethod/latin/dicttool/Diff.java | 90 +++++++++++++++++++---
2 files changed, 103 insertions(+), 12 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 4abed9f7f..93db8e833 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -143,11 +143,34 @@ public final class FusionDictionary implements Iterable {
return NOT_A_TERMINAL != mFrequency;
}
- @UsedForTesting
public int getFrequency() {
return mFrequency;
}
+ public boolean getIsNotAWord() {
+ return mIsNotAWord;
+ }
+
+ public boolean getIsBlacklistEntry() {
+ return mIsBlacklistEntry;
+ }
+
+ public ArrayList getShortcutTargets() {
+ // We don't want write permission to escape outside the package, so we return a copy
+ if (null == mShortcutTargets) return null;
+ final ArrayList copyOfShortcutTargets = new ArrayList();
+ copyOfShortcutTargets.addAll(mShortcutTargets);
+ return copyOfShortcutTargets;
+ }
+
+ public ArrayList getBigrams() {
+ // We don't want write permission to escape outside the package, so we return a copy
+ if (null == mBigrams) return null;
+ final ArrayList copyOfBigrams = new ArrayList();
+ copyOfBigrams.addAll(mBigrams);
+ return copyOfBigrams;
+ }
+
public boolean hasSeveralChars() {
assert(mChars.length > 0);
return 1 < mChars.length;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
index 60ba9383d..ad5f4e2b2 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
@@ -17,8 +17,13 @@
package com.android.inputmethod.latin.dicttool;
import com.android.inputmethod.latin.makedict.FusionDictionary;
+import com.android.inputmethod.latin.makedict.FusionDictionary.CharGroup;
+import com.android.inputmethod.latin.makedict.FusionDictionary.WeightedString;
+import com.android.inputmethod.latin.makedict.Word;
import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashMap;
public class Diff extends Dicttool.Command {
public static final String COMMAND = "diff";
@@ -57,22 +62,20 @@ public class Diff extends Dicttool.Command {
System.out.println("Header :");
diffHeaders(dict0, dict1);
if (languageDiffers(dict0, dict1)) {
- // diffHeaders returns whether the language is different. If it is, we should bail
- // to avoid flooding the output with thousands of useless word-level diffs.
+ // We only check for the language here. The rationale is that one may meaningfully
+ // diff a en_US with a en_GB dictionary, but someone who diffs a de dict with a
+ // pt_BR dict is almost certainly only interested in header-level diff, and the word
+ // diff would be very large, meaningless, and annoying.
return;
}
System.out.println("Body :");
}
- // TODO: implement the word-level diff
+ diffWords(dict0, dict1);
}
private static boolean languageDiffers(final FusionDictionary dict0,
final FusionDictionary dict1) {
// If either of the dictionaries have no locale, assume it's okay
- // We only check for the language here. The rationale is that one may meaningfully diff
- // a en_US with a en_GB dictionary, but someone who diffs a de dict with a pt_BR dict
- // is almost certainly only interested in header-level diff, and the word diff would be very
- // large, meaningless, and annoying.
if (null == dict0.mOptions.mAttributes.get("locale")) return true;
if (null == dict1.mOptions.mAttributes.get("locale")) return true;
final String dict0Lang = dict0.mOptions.mAttributes.get("locale").split("_", 3)[0];
@@ -91,6 +94,8 @@ public class Diff extends Dicttool.Command {
+ dict0.mOptions.mGermanUmlautProcessing + " <=> "
+ dict1.mOptions.mGermanUmlautProcessing);
}
+ final HashMap options1 =
+ (HashMap)dict1.mOptions.mAttributes.clone();
for (final String optionKey : dict0.mOptions.mAttributes.keySet()) {
if (!dict0.mOptions.mAttributes.get(optionKey).equals(
dict1.mOptions.mAttributes.get(optionKey))) {
@@ -98,11 +103,74 @@ public class Diff extends Dicttool.Command {
+ dict0.mOptions.mAttributes.get(optionKey) + " <=> "
+ dict1.mOptions.mAttributes.get(optionKey));
}
- dict1.mOptions.mAttributes.remove(optionKey);
+ options1.remove(optionKey);
}
- for (final String optionKey : dict1.mOptions.mAttributes.keySet()) {
- System.out.println(" " + optionKey + " : null <=> "
- + dict1.mOptions.mAttributes.get(optionKey));
+ for (final String optionKey : options1.keySet()) {
+ System.out.println(" " + optionKey + " : null <=> " + options1.get(optionKey));
+ }
+ }
+
+ private static void diffWords(final FusionDictionary dict0, final FusionDictionary dict1) {
+ for (final Word word0 : dict0) {
+ final CharGroup word1 = dict1.findWordInTree(dict1.mRoot, word0.mWord);
+ if (null == word1) {
+ // This word is not in dict1
+ System.out.println("Deleted: " + word0.mWord + " " + word0.mFrequency);
+ } else {
+ // We found the word. Compare frequencies, shortcuts, bigrams
+ if (word0.mFrequency != word1.getFrequency()) {
+ System.out.println("Freq changed: " + word0.mWord + " " + word0.mFrequency
+ + " -> " + word1.getFrequency());
+ }
+ if (word0.mIsNotAWord != word1.getIsNotAWord()) {
+ System.out.println("Not a word: " + word0.mWord + " " + word0.mIsNotAWord
+ + " -> " + word1.getIsNotAWord());
+ }
+ if (word0.mIsBlacklistEntry != word1.getIsBlacklistEntry()) {
+ System.out.println("Blacklist: " + word0.mWord + " " + word0.mIsBlacklistEntry
+ + " -> " + word1.getIsBlacklistEntry());
+ }
+ diffAttributes(word0.mWord, word0.mBigrams, word1.getBigrams());
+ diffAttributes(word0.mWord, word0.mShortcutTargets, word1.getShortcutTargets());
+ }
+ }
+ }
+
+ private static void diffAttributes(final String word, final ArrayList list0,
+ final ArrayList list1) {
+ if (null == list1) {
+ if (null == list0) return;
+ for (final WeightedString attribute0 : list0) {
+ System.out.println("Bigram removed: " + word + " " + attribute0.mWord + " "
+ + attribute0.mFrequency);
+ }
+ } else if (null != list0) {
+ for (final WeightedString attribute0 : list0) {
+ // The following tests with #equals(). The WeightedString#equals() method returns
+ // true if both the string and the frequency are the same.
+ if (!list1.contains(attribute0)) {
+ // Search for a word with the same string but a different frequency
+ for (final WeightedString attribute1 : list1) {
+ if (attribute0.mWord.equals(attribute1.mWord)) {
+ System.out.println("Bigram freq changed: " + word + " "
+ + attribute0.mWord + " " + attribute0.mFrequency + " -> "
+ + attribute1.mFrequency);
+ list1.remove(attribute1);
+ break;
+ }
+ // We come here if we haven't found any matching string.
+ System.out.println("Bigram removed: " + word + " " + attribute0.mWord);
+ }
+ } else {
+ list1.remove(attribute0);
+ }
+ }
+ }
+ // We removed any matching word that we found, so now list1 only contains words that
+ // are not included in list0.
+ for (final WeightedString attribute1 : list1) {
+ System.out.println("Bigram added: " + word + " " + attribute1.mWord + " "
+ + attribute1.mFrequency);
}
}
}
--
cgit v1.2.3-83-g751a
From f41389a74b02a01f7383b1a872db5fa65e81fa1e Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Mon, 29 Oct 2012 14:24:16 +0900
Subject: Remove warnings
Thanks Eclipse
Change-Id: I88e3979ed22be5d8be5a5accdde417c6b1a8bf2d
---
.../inputmethod/latin/makedict/BinaryDictIOUtils.java | 1 +
.../inputmethod/latin/makedict/BinaryDictInputOutput.java | 12 ++++--------
.../android/inputmethod/latin/makedict/FusionDictionary.java | 8 +++-----
.../inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java | 2 --
.../src/com/android/inputmethod/latin/dicttool/Diff.java | 4 ++--
.../src/com/android/inputmethod/latin/dicttool/Info.java | 2 +-
6 files changed, 11 insertions(+), 18 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
index 05f2d933c..ee0e9cd7e 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictIOUtils.java
@@ -565,6 +565,7 @@ public final class BinaryDictIOUtils {
return size;
}
+ @SuppressWarnings("unused")
private static void updateForwardLink(final FusionDictionaryBufferInterface buffer,
final int nodeOriginAddress, final int newNodeAddress,
final FormatOptions formatOptions) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
index 031306e1d..d1a3c7b0a 100644
--- a/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
+++ b/java/src/com/android/inputmethod/latin/makedict/BinaryDictInputOutput.java
@@ -77,12 +77,12 @@ public final class BinaryDictInputOutput {
@Override
public int readUnsignedByte() {
- return ((int)mBuffer.get()) & 0xFF;
+ return mBuffer.get() & 0xFF;
}
@Override
public int readUnsignedShort() {
- return ((int)mBuffer.getShort()) & 0xFFFF;
+ return mBuffer.getShort() & 0xFFFF;
}
@Override
@@ -474,11 +474,8 @@ public final class BinaryDictInputOutput {
}
}
- private static final int SINT8_MAX = 0x7F;
- private static final int SINT16_MAX = 0x7FFF;
private static final int SINT24_MAX = 0x7FFFFF;
private static final int MSB8 = 0x80;
- private static final int MSB16 = 0x8000;
private static final int MSB24 = 0x800000;
// End utility methods.
@@ -1711,7 +1708,7 @@ public final class BinaryDictInputOutput {
*
* Concretely this only tests the magic number.
*
- * @param filename The name of the file to test.
+ * @param file The file to test.
* @return true if it's a binary dictionary, false otherwise
*/
public static boolean isBinaryDictionary(final File file) {
@@ -1751,8 +1748,7 @@ public final class BinaryDictInputOutput {
final int bigramFrequency) {
final float stepSize = (FormatSpec.MAX_TERMINAL_FREQUENCY - unigramFrequency)
/ (1.5f + FormatSpec.MAX_BIGRAM_FREQUENCY);
- final float resultFreqFloat = (float)unigramFrequency
- + stepSize * (bigramFrequency + 1.0f);
+ final float resultFreqFloat = unigramFrequency + stepSize * (bigramFrequency + 1.0f);
return (int)resultFreqFloat;
}
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index 93db8e833..c588824fe 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.latin.makedict;
-import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
import java.util.ArrayList;
@@ -158,16 +157,15 @@ public final class FusionDictionary implements Iterable {
public ArrayList getShortcutTargets() {
// We don't want write permission to escape outside the package, so we return a copy
if (null == mShortcutTargets) return null;
- final ArrayList copyOfShortcutTargets = new ArrayList();
- copyOfShortcutTargets.addAll(mShortcutTargets);
+ final ArrayList copyOfShortcutTargets =
+ new ArrayList(mShortcutTargets);
return copyOfShortcutTargets;
}
public ArrayList getBigrams() {
// We don't want write permission to escape outside the package, so we return a copy
if (null == mBigrams) return null;
- final ArrayList copyOfBigrams = new ArrayList();
- copyOfBigrams.addAll(mBigrams);
+ final ArrayList copyOfBigrams = new ArrayList(mBigrams);
return copyOfBigrams;
}
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
index 4573fa6f7..0803b08d5 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java
@@ -17,7 +17,6 @@
package com.android.inputmethod.latin.dicttool;
import com.android.inputmethod.latin.makedict.BinaryDictInputOutput;
-import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.ByteBufferWrapper;
import com.android.inputmethod.latin.makedict.FusionDictionary;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
@@ -33,7 +32,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
-import java.nio.channels.FileChannel.MapMode;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
index ad5f4e2b2..9548f2509 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
@@ -95,7 +95,7 @@ public class Diff extends Dicttool.Command {
+ dict1.mOptions.mGermanUmlautProcessing);
}
final HashMap options1 =
- (HashMap)dict1.mOptions.mAttributes.clone();
+ new HashMap(dict1.mOptions.mAttributes);
for (final String optionKey : dict0.mOptions.mAttributes.keySet()) {
if (!dict0.mOptions.mAttributes.get(optionKey).equals(
dict1.mOptions.mAttributes.get(optionKey))) {
@@ -112,7 +112,7 @@ public class Diff extends Dicttool.Command {
private static void diffWords(final FusionDictionary dict0, final FusionDictionary dict1) {
for (final Word word0 : dict0) {
- final CharGroup word1 = dict1.findWordInTree(dict1.mRoot, word0.mWord);
+ final CharGroup word1 = FusionDictionary.findWordInTree(dict1.mRoot, word0.mWord);
if (null == word1) {
// This word is not in dict1
System.out.println("Deleted: " + word0.mWord + " " + word0.mFrequency);
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
index 6f1c020f2..7f25818fb 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Info.java
@@ -63,7 +63,7 @@ public class Info extends Dicttool.Command {
}
private static void showWordInfo(final FusionDictionary dict, final String word) {
- final CharGroup group = dict.findWordInTree(dict.mRoot, word);
+ final CharGroup group = FusionDictionary.findWordInTree(dict.mRoot, word);
if (null == group) {
System.out.println(word + " is not in the dictionary");
return;
--
cgit v1.2.3-83-g751a
From 240871ecafde7834ebb4270cd7758fc904a5f3a7 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Mon, 29 Oct 2012 14:46:34 +0900
Subject: Move code point constants from Keyboard to Constants class
Change-Id: Iee01d4d2b916d0b584531104ac865ae6e6370a3d
---
.../accessibility/KeyCodeDescriptionMapper.java | 33 +++++----
java/src/com/android/inputmethod/keyboard/Key.java | 11 +--
.../android/inputmethod/keyboard/KeyDetector.java | 4 +-
.../com/android/inputmethod/keyboard/Keyboard.java | 71 +------------------
.../inputmethod/keyboard/MainKeyboardView.java | 16 ++---
.../inputmethod/keyboard/PointerTracker.java | 19 ++---
.../inputmethod/keyboard/ProximityInfo.java | 7 +-
.../keyboard/internal/KeySpecParser.java | 13 ++--
.../keyboard/internal/KeyboardCodesSet.java | 32 ++++-----
.../keyboard/internal/KeyboardParams.java | 4 +-
.../keyboard/internal/KeyboardState.java | 33 +++++----
.../inputmethod/keyboard/internal/MoreKeySpec.java | 10 +--
.../latin/AudioAndHapticFeedbackManager.java | 7 +-
.../com/android/inputmethod/latin/Constants.java | 70 +++++++++++++++++++
.../latin/ContactsBinaryDictionary.java | 4 +-
.../inputmethod/latin/ExpandableDictionary.java | 5 +-
.../com/android/inputmethod/latin/LatinIME.java | 80 +++++++++++-----------
.../inputmethod/latin/RichInputConnection.java | 7 +-
.../com/android/inputmethod/latin/StringUtils.java | 19 +++--
.../src/com/android/inputmethod/latin/Suggest.java | 3 +-
.../android/inputmethod/latin/WordComposer.java | 6 +-
.../inputmethod/research/ResearchLogger.java | 8 +--
.../android/inputmethod/research/Statistics.java | 4 +-
.../keyboard/internal/KeySpecParserTests.java | 10 +--
.../keyboard/internal/KeyboardStateTestsBase.java | 2 +-
.../keyboard/internal/MockKeyboardSwitcher.java | 57 ++++++++-------
.../inputmethod/latin/BlueUnderlineTests.java | 8 +--
.../android/inputmethod/latin/InputLogicTests.java | 26 ++++---
28 files changed, 282 insertions(+), 287 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 32618ad85..b87ae3a15 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -26,6 +26,7 @@ import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import java.util.HashMap;
@@ -61,17 +62,19 @@ public final class KeyCodeDescriptionMapper {
mKeyLabelMap.put(":-)", R.string.spoken_description_smiley);
// Special non-character codes defined in Keyboard
- mKeyCodeMap.put(Keyboard.CODE_SPACE, R.string.spoken_description_space);
- mKeyCodeMap.put(Keyboard.CODE_DELETE, R.string.spoken_description_delete);
- mKeyCodeMap.put(Keyboard.CODE_ENTER, R.string.spoken_description_return);
- mKeyCodeMap.put(Keyboard.CODE_SETTINGS, R.string.spoken_description_settings);
- mKeyCodeMap.put(Keyboard.CODE_SHIFT, R.string.spoken_description_shift);
- mKeyCodeMap.put(Keyboard.CODE_SHORTCUT, R.string.spoken_description_mic);
- mKeyCodeMap.put(Keyboard.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol);
- mKeyCodeMap.put(Keyboard.CODE_TAB, R.string.spoken_description_tab);
- mKeyCodeMap.put(Keyboard.CODE_LANGUAGE_SWITCH, R.string.spoken_description_language_switch);
- mKeyCodeMap.put(Keyboard.CODE_ACTION_NEXT, R.string.spoken_description_action_next);
- mKeyCodeMap.put(Keyboard.CODE_ACTION_PREVIOUS, R.string.spoken_description_action_previous);
+ mKeyCodeMap.put(Constants.CODE_SPACE, R.string.spoken_description_space);
+ mKeyCodeMap.put(Constants.CODE_DELETE, R.string.spoken_description_delete);
+ mKeyCodeMap.put(Constants.CODE_ENTER, R.string.spoken_description_return);
+ mKeyCodeMap.put(Constants.CODE_SETTINGS, R.string.spoken_description_settings);
+ mKeyCodeMap.put(Constants.CODE_SHIFT, R.string.spoken_description_shift);
+ mKeyCodeMap.put(Constants.CODE_SHORTCUT, R.string.spoken_description_mic);
+ mKeyCodeMap.put(Constants.CODE_SWITCH_ALPHA_SYMBOL, R.string.spoken_description_to_symbol);
+ mKeyCodeMap.put(Constants.CODE_TAB, R.string.spoken_description_tab);
+ mKeyCodeMap.put(Constants.CODE_LANGUAGE_SWITCH,
+ R.string.spoken_description_language_switch);
+ mKeyCodeMap.put(Constants.CODE_ACTION_NEXT, R.string.spoken_description_action_next);
+ mKeyCodeMap.put(Constants.CODE_ACTION_PREVIOUS,
+ R.string.spoken_description_action_previous);
}
/**
@@ -97,17 +100,17 @@ public final class KeyCodeDescriptionMapper {
boolean shouldObscure) {
final int code = key.mCode;
- if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
final String description = getDescriptionForSwitchAlphaSymbol(context, keyboard);
if (description != null)
return description;
}
- if (code == Keyboard.CODE_SHIFT) {
+ if (code == Constants.CODE_SHIFT) {
return getDescriptionForShiftKey(context, keyboard);
}
- if (code == Keyboard.CODE_ACTION_ENTER) {
+ if (code == Constants.CODE_ACTION_ENTER) {
return getDescriptionForActionKey(context, keyboard, key);
}
@@ -121,7 +124,7 @@ public final class KeyCodeDescriptionMapper {
}
// Just attempt to speak the description.
- if (key.mCode != Keyboard.CODE_UNSPECIFIED) {
+ if (key.mCode != Constants.CODE_UNSPECIFIED) {
return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
}
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 30812e8c3..7346a9c38 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -16,11 +16,11 @@
package com.android.inputmethod.keyboard;
-import static com.android.inputmethod.keyboard.Keyboard.CODE_OUTPUT_TEXT;
-import static com.android.inputmethod.keyboard.Keyboard.CODE_SHIFT;
-import static com.android.inputmethod.keyboard.Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
-import static com.android.inputmethod.keyboard.Keyboard.CODE_UNSPECIFIED;
import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
+import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
+import static com.android.inputmethod.latin.Constants.CODE_SHIFT;
+import static com.android.inputmethod.latin.Constants.CODE_SWITCH_ALPHA_SYMBOL;
+import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -39,6 +39,7 @@ import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
import com.android.inputmethod.keyboard.internal.KeyboardRow;
import com.android.inputmethod.keyboard.internal.MoreKeySpec;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.ResourceUtils;
import com.android.inputmethod.latin.StringUtils;
@@ -453,7 +454,7 @@ public class Key implements Comparable {
label = "/" + mLabel;
}
return String.format("%s%s %d,%d %dx%d %s/%s/%s",
- Keyboard.printableCode(mCode), label, mX, mY, mWidth, mHeight, mHintLabel,
+ Constants.printableCode(mCode), label, mX, mY, mWidth, mHeight, mHintLabel,
KeyboardIconsSet.getIconName(mIconId), backgroundName(mBackgroundType));
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index aa683c1d7..0a91284d0 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -118,7 +118,7 @@ public class KeyDetector {
}
public static String printableCode(Key key) {
- return key != null ? Keyboard.printableCode(key.mCode) : "none";
+ return key != null ? Constants.printableCode(key.mCode) : "none";
}
public static String printableCodes(int[] codes) {
@@ -127,7 +127,7 @@ public class KeyDetector {
for (final int code : codes) {
if (code == Constants.NOT_A_CODE) break;
if (addDelimiter) sb.append(", ");
- sb.append(Keyboard.printableCode(code));
+ sb.append(Constants.printableCode(code));
addDelimiter = true;
}
return "[" + sb + "]";
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index b7c7f415d..dd2e3d392 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -16,13 +16,13 @@
package com.android.inputmethod.keyboard;
-import android.util.Log;
import android.util.SparseArray;
import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.Constants;
@@ -45,46 +45,6 @@ import com.android.inputmethod.latin.CollectionUtils;
*
*/
public class Keyboard {
- private static final String TAG = Keyboard.class.getSimpleName();
-
- /** Some common keys code. Must be positive.
- * These should be aligned with values/keycodes.xml
- */
- public static final int CODE_ENTER = '\n';
- public static final int CODE_TAB = '\t';
- public static final int CODE_SPACE = ' ';
- public static final int CODE_PERIOD = '.';
- public static final int CODE_DASH = '-';
- public static final int CODE_SINGLE_QUOTE = '\'';
- public static final int CODE_DOUBLE_QUOTE = '"';
- public static final int CODE_QUESTION_MARK = '?';
- public static final int CODE_EXCLAMATION_MARK = '!';
- // TODO: Check how this should work for right-to-left languages. It seems to stand
- // that for rtl languages, a closing parenthesis is a left parenthesis. Is this
- // managed by the font? Or is it a different char?
- public static final int CODE_CLOSING_PARENTHESIS = ')';
- public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
- public static final int CODE_CLOSING_CURLY_BRACKET = '}';
- public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
-
- /** Special keys code. Must be negative.
- * These should be aligned with KeyboardCodesSet.ID_TO_NAME[],
- * KeyboardCodesSet.DEFAULT[] and KeyboardCodesSet.RTL[]
- */
- public static final int CODE_SHIFT = -1;
- public static final int CODE_SWITCH_ALPHA_SYMBOL = -2;
- public static final int CODE_OUTPUT_TEXT = -3;
- public static final int CODE_DELETE = -4;
- public static final int CODE_SETTINGS = -5;
- public static final int CODE_SHORTCUT = -6;
- public static final int CODE_ACTION_ENTER = -7;
- public static final int CODE_ACTION_NEXT = -8;
- public static final int CODE_ACTION_PREVIOUS = -9;
- public static final int CODE_LANGUAGE_SWITCH = -10;
- public static final int CODE_RESEARCH = -11;
- // Code value representing the code is not specified.
- public static final int CODE_UNSPECIFIED = -12;
-
public final KeyboardId mId;
public final int mThemeId;
@@ -163,7 +123,7 @@ public class Keyboard {
}
public Key getKey(final int code) {
- if (code == CODE_UNSPECIFIED) {
+ if (code == Constants.CODE_UNSPECIFIED) {
return null;
}
synchronized (mKeyCache) {
@@ -197,10 +157,6 @@ public class Keyboard {
return false;
}
- public static boolean isLetterCode(final int code) {
- return code >= CODE_SPACE;
- }
-
@Override
public String toString() {
return mId.toString();
@@ -219,27 +175,4 @@ public class Keyboard {
final int adjustedY = Math.max(0, Math.min(y, mOccupiedHeight - 1));
return mProximityInfo.getNearestKeys(adjustedX, adjustedY);
}
-
- public static String printableCode(final int code) {
- switch (code) {
- case CODE_SHIFT: return "shift";
- case CODE_SWITCH_ALPHA_SYMBOL: return "symbol";
- case CODE_OUTPUT_TEXT: return "text";
- case CODE_DELETE: return "delete";
- case CODE_SETTINGS: return "settings";
- case CODE_SHORTCUT: return "shortcut";
- case CODE_ACTION_ENTER: return "actionEnter";
- case CODE_ACTION_NEXT: return "actionNext";
- case CODE_ACTION_PREVIOUS: return "actionPrevious";
- case CODE_LANGUAGE_SWITCH: return "languageSwitch";
- case CODE_UNSPECIFIED: return "unspec";
- case CODE_TAB: return "tab";
- case CODE_ENTER: return "enter";
- default:
- if (code <= 0) Log.w(TAG, "Unknown non-positive key code=" + code);
- if (code < CODE_SPACE) return String.format("'\\u%02x'", code);
- if (code < 0x100) return String.format("'%c'", code);
- return String.format("'\\u%04x'", code);
- }
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 5b6820fa6..4efc526bf 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -227,7 +227,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
cancelLongPressTimer();
final int delay;
switch (code) {
- case Keyboard.CODE_SHIFT:
+ case Constants.CODE_SHIFT:
delay = mLongPressShiftKeyTimeout;
break;
default:
@@ -248,7 +248,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
final Key key = tracker.getKey();
final int delay;
switch (key.mCode) {
- case Keyboard.CODE_SHIFT:
+ case Constants.CODE_SHIFT:
delay = mLongPressShiftKeyTimeout;
break;
default:
@@ -305,7 +305,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
// When user hits the space or the enter key, just cancel the while-typing timer.
final int typedCode = typedKey.mCode;
- if (typedCode == Keyboard.CODE_SPACE || typedCode == Keyboard.CODE_ENTER) {
+ if (typedCode == Constants.CODE_SPACE || typedCode == Constants.CODE_ENTER) {
startWhileTypingFadeinAnimation(keyboardView);
return;
}
@@ -487,7 +487,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
mTouchScreenRegulator.setKeyboard(keyboard);
mMoreKeysPanelCache.clear();
- mSpaceKey = keyboard.getKey(Keyboard.CODE_SPACE);
+ mSpaceKey = keyboard.getKey(Constants.CODE_SPACE);
mSpaceIcon = (mSpaceKey != null)
? mSpaceKey.getIcon(keyboard.mIconsSet, Constants.Color.ALPHA_OPAQUE) : null;
final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
@@ -604,7 +604,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode);
return true;
}
- if (primaryCode == Keyboard.CODE_SPACE || primaryCode == Keyboard.CODE_LANGUAGE_SWITCH) {
+ if (primaryCode == Constants.CODE_SPACE || primaryCode == Constants.CODE_LANGUAGE_SWITCH) {
// Long pressing the space key invokes IME switcher dialog.
if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) {
tracker.onLongPressed();
@@ -875,7 +875,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
public void updateShortcutKey(final boolean available) {
final Keyboard keyboard = getKeyboard();
if (keyboard == null) return;
- final Key shortcutKey = keyboard.getKey(Keyboard.CODE_SHORTCUT);
+ final Key shortcutKey = keyboard.getKey(Constants.CODE_SHORTCUT);
if (shortcutKey == null) return;
shortcutKey.setEnabled(available);
invalidateKey(shortcutKey);
@@ -924,13 +924,13 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
if (key.altCodeWhileTyping() && key.isEnabled()) {
params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha;
}
- if (key.mCode == Keyboard.CODE_SPACE) {
+ if (key.mCode == Constants.CODE_SPACE) {
drawSpacebar(key, canvas, paint);
// Whether space key needs to show the "..." popup hint for special purposes
if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) {
drawKeyPopupHint(key, canvas, paint, params);
}
- } else if (key.mCode == Keyboard.CODE_LANGUAGE_SWITCH) {
+ } else if (key.mCode == Constants.CODE_LANGUAGE_SWITCH) {
super.onDrawKeyTopVisuals(key, canvas, paint, params);
drawKeyPopupHint(key, canvas, paint, params);
} else {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 92e1f5473..141436a6d 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -27,6 +27,7 @@ import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokePara
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
@@ -453,8 +454,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
final boolean altersCode = key.altCodeWhileTyping() && mTimerProxy.isTypingState();
final int code = altersCode ? key.getAltCode() : primaryCode;
if (DEBUG_LISTENER) {
- final String output = code == Keyboard.CODE_OUTPUT_TEXT
- ? key.getOutputText() : Keyboard.printableCode(code);
+ final String output = code == Constants.CODE_OUTPUT_TEXT
+ ? key.getOutputText() : Constants.printableCode(code);
Log.d(TAG, String.format("[%d] onCodeInput: %4d %4d %s%s%s", mPointerId, x, y,
output, ignoreModifierKey ? " ignoreModifier" : "",
altersCode ? " altersCode" : "", key.isEnabled() ? "" : " disabled"));
@@ -469,9 +470,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// Even if the key is disabled, it should respond if it is in the altCodeWhileTyping state.
if (key.isEnabled() || altersCode) {
sTimeRecorder.onCodeInput(code, eventTime);
- if (code == Keyboard.CODE_OUTPUT_TEXT) {
+ if (code == Constants.CODE_OUTPUT_TEXT) {
mListener.onTextInput(key.getOutputText());
- } else if (code != Keyboard.CODE_UNSPECIFIED) {
+ } else if (code != Constants.CODE_UNSPECIFIED) {
mListener.onCodeInput(code, x, y);
}
}
@@ -487,7 +488,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
final boolean ignoreModifierKey = mIsInSlidingKeyInputFromModifier && key.isModifier();
if (DEBUG_LISTENER) {
Log.d(TAG, String.format("[%d] onRelease : %s%s%s%s", mPointerId,
- Keyboard.printableCode(primaryCode),
+ Constants.printableCode(primaryCode),
withSliding ? " sliding" : "", ignoreModifierKey ? " ignoreModifier" : "",
key.isEnabled() ? "": " disabled"));
}
@@ -952,8 +953,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
+ " phantom sudden move event (distance=%d) is translated to "
+ "up[%d,%d,%s]/down[%d,%d,%s] events", mPointerId,
getDistance(x, y, lastX, lastY),
- lastX, lastY, Keyboard.printableCode(oldKey.mCode),
- x, y, Keyboard.printableCode(key.mCode)));
+ lastX, lastY, Constants.printableCode(oldKey.mCode),
+ x, y, Constants.printableCode(key.mCode)));
}
// TODO: This should be moved to outside of this nested if-clause?
if (ProductionFlag.IS_EXPERIMENTAL) {
@@ -978,8 +979,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
+ " bogus down-move-up event (raidus=%.2f key diagonal) is "
+ " translated to up[%d,%d,%s]/down[%d,%d,%s] events",
mPointerId, radiusRatio,
- lastX, lastY, Keyboard.printableCode(oldKey.mCode),
- x, y, Keyboard.printableCode(key.mCode)));
+ lastX, lastY, Constants.printableCode(oldKey.mCode),
+ x, y, Constants.printableCode(key.mCode)));
}
onUpEventInternal(eventTime);
onDownEventInternal(x, y, eventTime);
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 94fc80507..ed01f3458 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -172,7 +172,8 @@ public final class ProximityInfo {
Log.d(TAG, String.format(
" [%2d] row=%d x/y/r=%7.2f/%7.2f/%5.2f %s code=%s", i, row,
sweetSpotCenterXs[i], sweetSpotCenterYs[i], sweetSpotRadii[i],
- row < rows ? "correct" : "default", Keyboard.printableCode(key.mCode)));
+ (row < rows ? "correct" : "default"),
+ Constants.printableCode(key.mCode)));
}
}
} else {
@@ -238,7 +239,7 @@ public final class ProximityInfo {
return;
}
int index = 0;
- if (primaryKeyCode > Keyboard.CODE_SPACE) {
+ if (primaryKeyCode > Constants.CODE_SPACE) {
dest[index++] = primaryKeyCode;
}
final Key[] nearestKeys = getNearestKeys(x, y);
@@ -247,7 +248,7 @@ public final class ProximityInfo {
break;
}
final int code = key.mCode;
- if (code <= Keyboard.CODE_SPACE) {
+ if (code <= Constants.CODE_SPACE) {
break;
}
dest[index++] = code;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index 2caa5eb02..9f6e2f37e 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -16,12 +16,13 @@
package com.android.inputmethod.keyboard.internal;
-import static com.android.inputmethod.keyboard.Keyboard.CODE_UNSPECIFIED;
+import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
+import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
import android.text.TextUtils;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.StringUtils;
@@ -172,7 +173,7 @@ public final class KeySpecParser {
if (indexOfLabelEnd(moreKeySpec, end + 1) >= 0) {
throw new KeySpecParserError("Multiple " + LABEL_END + ": " + moreKeySpec);
}
- return parseCode(moreKeySpec.substring(end + 1), codesSet, Keyboard.CODE_UNSPECIFIED);
+ return parseCode(moreKeySpec.substring(end + 1), codesSet, CODE_UNSPECIFIED);
}
final String outputText = getOutputTextInternal(moreKeySpec);
if (outputText != null) {
@@ -181,14 +182,14 @@ public final class KeySpecParser {
if (StringUtils.codePointCount(outputText) == 1) {
return outputText.codePointAt(0);
}
- return Keyboard.CODE_OUTPUT_TEXT;
+ return CODE_OUTPUT_TEXT;
}
final String label = getLabel(moreKeySpec);
// Code is automatically generated for one letter label.
if (StringUtils.codePointCount(label) == 1) {
return label.codePointAt(0);
}
- return Keyboard.CODE_OUTPUT_TEXT;
+ return CODE_OUTPUT_TEXT;
}
public static int parseCode(final String text, final KeyboardCodesSet codesSet,
@@ -468,7 +469,7 @@ public final class KeySpecParser {
public static int toUpperCaseOfCodeForLocale(final int code, final boolean needsToUpperCase,
final Locale locale) {
- if (!Keyboard.isLetterCode(code) || !needsToUpperCase) return code;
+ if (!Constants.isLetterCode(code) || !needsToUpperCase) return code;
final String text = new String(new int[] { code } , 0, 1);
final String casedText = KeySpecParser.toUpperCaseOfStringForLocale(
text, needsToUpperCase, locale);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
index 840d7133d..428e31ccd 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
@@ -16,8 +16,8 @@
package com.android.inputmethod.keyboard.internal;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.Constants;
import java.util.HashMap;
@@ -74,21 +74,21 @@ public final class KeyboardCodesSet {
private static final int CODE_RIGHT_CURLY_BRACKET = '}';
private static final int[] DEFAULT = {
- Keyboard.CODE_TAB,
- Keyboard.CODE_ENTER,
- Keyboard.CODE_SPACE,
- Keyboard.CODE_SHIFT,
- Keyboard.CODE_SWITCH_ALPHA_SYMBOL,
- Keyboard.CODE_OUTPUT_TEXT,
- Keyboard.CODE_DELETE,
- Keyboard.CODE_SETTINGS,
- Keyboard.CODE_SHORTCUT,
- Keyboard.CODE_ACTION_ENTER,
- Keyboard.CODE_ACTION_NEXT,
- Keyboard.CODE_ACTION_PREVIOUS,
- Keyboard.CODE_LANGUAGE_SWITCH,
- Keyboard.CODE_RESEARCH,
- Keyboard.CODE_UNSPECIFIED,
+ Constants.CODE_TAB,
+ Constants.CODE_ENTER,
+ Constants.CODE_SPACE,
+ Constants.CODE_SHIFT,
+ Constants.CODE_SWITCH_ALPHA_SYMBOL,
+ Constants.CODE_OUTPUT_TEXT,
+ Constants.CODE_DELETE,
+ Constants.CODE_SETTINGS,
+ Constants.CODE_SHORTCUT,
+ Constants.CODE_ACTION_ENTER,
+ Constants.CODE_ACTION_NEXT,
+ Constants.CODE_ACTION_PREVIOUS,
+ Constants.CODE_LANGUAGE_SWITCH,
+ Constants.CODE_RESEARCH,
+ Constants.CODE_UNSPECIFIED,
CODE_LEFT_PARENTHESIS,
CODE_RIGHT_PARENTHESIS,
CODE_LESS_THAN_SIGN,
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index e6fe50e02..642e1a18c 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -19,9 +19,9 @@ package com.android.inputmethod.keyboard.internal;
import android.util.SparseIntArray;
import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.latin.CollectionUtils;
+import com.android.inputmethod.latin.Constants;
import java.util.ArrayList;
import java.util.TreeSet;
@@ -89,7 +89,7 @@ public class KeyboardParams {
mKeys.add(key);
updateHistogram(key);
}
- if (key.mCode == Keyboard.CODE_SHIFT) {
+ if (key.mCode == Constants.CODE_SHIFT) {
mShiftKeys.add(key);
}
if (key.altCodeWhileTyping()) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index 58cc8972a..5f67ae05f 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -19,7 +19,6 @@ package com.android.inputmethod.keyboard.internal;
import android.text.TextUtils;
import android.util.Log;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.Constants;
/**
@@ -300,12 +299,12 @@ public final class KeyboardState {
public void onPressKey(int code, boolean isSinglePointer, int autoCaps) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onPressKey: code=" + Keyboard.printableCode(code)
+ Log.d(TAG, "onPressKey: code=" + Constants.printableCode(code)
+ " single=" + isSinglePointer + " autoCaps=" + autoCaps + " " + this);
}
- if (code == Keyboard.CODE_SHIFT) {
+ if (code == Constants.CODE_SHIFT) {
onPressShift();
- } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ } else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
onPressSymbol();
} else {
mSwitchActions.cancelDoubleTapTimer();
@@ -333,12 +332,12 @@ public final class KeyboardState {
public void onReleaseKey(int code, boolean withSliding) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onReleaseKey: code=" + Keyboard.printableCode(code)
+ Log.d(TAG, "onReleaseKey: code=" + Constants.printableCode(code)
+ " sliding=" + withSliding + " " + this);
}
- if (code == Keyboard.CODE_SHIFT) {
+ if (code == Constants.CODE_SHIFT) {
onReleaseShift(withSliding);
- } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ } else if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
onReleaseSymbol(withSliding);
}
}
@@ -365,9 +364,9 @@ public final class KeyboardState {
public void onLongPressTimeout(int code) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onLongPressTimeout: code=" + Keyboard.printableCode(code) + " " + this);
+ Log.d(TAG, "onLongPressTimeout: code=" + Constants.printableCode(code) + " " + this);
}
- if (mIsAlphabetMode && code == Keyboard.CODE_SHIFT) {
+ if (mIsAlphabetMode && code == Constants.CODE_SHIFT) {
mLongPressShiftLockFired = true;
mSwitchActions.hapticAndAudioFeedback(code);
}
@@ -434,7 +433,7 @@ public final class KeyboardState {
setShifted(MANUAL_SHIFT);
mShiftKeyState.onPress();
}
- mSwitchActions.startLongPressTimer(Keyboard.CODE_SHIFT);
+ mSwitchActions.startLongPressTimer(Constants.CODE_SHIFT);
}
} else {
// In symbol mode, just toggle symbol and symbol more keyboard.
@@ -514,7 +513,7 @@ public final class KeyboardState {
}
private static boolean isSpaceCharacter(int c) {
- return c == Keyboard.CODE_SPACE || c == Keyboard.CODE_ENTER;
+ return c == Constants.CODE_SPACE || c == Constants.CODE_ENTER;
}
private boolean isLayoutSwitchBackCharacter(int c) {
@@ -525,14 +524,14 @@ public final class KeyboardState {
public void onCodeInput(int code, boolean isSinglePointer, int autoCaps) {
if (DEBUG_EVENT) {
- Log.d(TAG, "onCodeInput: code=" + Keyboard.printableCode(code)
+ Log.d(TAG, "onCodeInput: code=" + Constants.printableCode(code)
+ " single=" + isSinglePointer
+ " autoCaps=" + autoCaps + " " + this);
}
switch (mSwitchState) {
case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
- if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ if (code == Constants.CODE_SWITCH_ALPHA_SYMBOL) {
// Detected only the mode change key has been pressed, and then released.
if (mIsAlphabetMode) {
mSwitchState = SWITCH_STATE_ALPHA;
@@ -548,7 +547,7 @@ public final class KeyboardState {
}
break;
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
- if (code == Keyboard.CODE_SHIFT) {
+ if (code == Constants.CODE_SHIFT) {
// Detected only the shift key has been pressed on symbol layout, and then released.
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
} else if (isSinglePointer) {
@@ -559,8 +558,8 @@ public final class KeyboardState {
}
break;
case SWITCH_STATE_SYMBOL_BEGIN:
- if (!isSpaceCharacter(code) && (Keyboard.isLetterCode(code)
- || code == Keyboard.CODE_OUTPUT_TEXT)) {
+ if (!isSpaceCharacter(code) && (Constants.isLetterCode(code)
+ || code == Constants.CODE_OUTPUT_TEXT)) {
mSwitchState = SWITCH_STATE_SYMBOL;
}
// Switch back to alpha keyboard mode immediately if user types one of the switch back
@@ -581,7 +580,7 @@ public final class KeyboardState {
}
// If the code is a letter, update keyboard shift state.
- if (Keyboard.isLetterCode(code)) {
+ if (Constants.isLetterCode(code)) {
updateAlphabetShiftState(autoCaps);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
index 550391b49..ca16163d4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
@@ -18,7 +18,7 @@ package com.android.inputmethod.keyboard.internal;
import android.text.TextUtils;
-import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.StringUtils;
import java.util.Locale;
@@ -35,10 +35,10 @@ public final class MoreKeySpec {
KeySpecParser.getLabel(moreKeySpec), needsToUpperCase, locale);
final int code = KeySpecParser.toUpperCaseOfCodeForLocale(
KeySpecParser.getCode(moreKeySpec, codesSet), needsToUpperCase, locale);
- if (code == Keyboard.CODE_UNSPECIFIED) {
+ if (code == Constants.CODE_UNSPECIFIED) {
// Some letter, for example German Eszett (U+00DF: "ß"), has multiple characters
// upper case representation ("SS").
- mCode = Keyboard.CODE_OUTPUT_TEXT;
+ mCode = Constants.CODE_OUTPUT_TEXT;
mOutputText = mLabel;
} else {
mCode = code;
@@ -75,8 +75,8 @@ public final class MoreKeySpec {
public String toString() {
final String label = (mIconId == KeyboardIconsSet.ICON_UNDEFINED ? mLabel
: KeySpecParser.PREFIX_ICON + KeyboardIconsSet.getIconName(mIconId));
- final String output = (mCode == Keyboard.CODE_OUTPUT_TEXT ? mOutputText
- : Keyboard.printableCode(mCode));
+ final String output = (mCode == Constants.CODE_OUTPUT_TEXT ? mOutputText
+ : Constants.printableCode(mCode));
if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) {
return output;
} else {
diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
index 91bbd54c7..024726391 100644
--- a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
+++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
@@ -21,7 +21,6 @@ import android.media.AudioManager;
import android.view.HapticFeedbackConstants;
import android.view.View;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.VibratorUtils;
/**
@@ -62,13 +61,13 @@ public final class AudioAndHapticFeedbackManager {
if (mSoundOn) {
final int sound;
switch (primaryCode) {
- case Keyboard.CODE_DELETE:
+ case Constants.CODE_DELETE:
sound = AudioManager.FX_KEYPRESS_DELETE;
break;
- case Keyboard.CODE_ENTER:
+ case Constants.CODE_ENTER:
sound = AudioManager.FX_KEYPRESS_RETURN;
break;
- case Keyboard.CODE_SPACE:
+ case Constants.CODE_SPACE:
sound = AudioManager.FX_KEYPRESS_SPACEBAR;
break;
default:
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index 57e12a64f..d10ed8efb 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -16,7 +16,11 @@
package com.android.inputmethod.latin;
+import android.util.Log;
+
public final class Constants {
+ private static final String TAG = Constants.class.getSimpleName();
+
public static final class Color {
/**
* The alpha value for fully opaque.
@@ -141,6 +145,72 @@ public final class Constants {
public static final int SUGGESTION_STRIP_COORDINATE = -2;
public static final int SPELL_CHECKER_COORDINATE = -3;
+ /**
+ * Some common keys code. Must be positive.
+ */
+ public static final int CODE_ENTER = '\n';
+ public static final int CODE_TAB = '\t';
+ public static final int CODE_SPACE = ' ';
+ public static final int CODE_PERIOD = '.';
+ public static final int CODE_DASH = '-';
+ public static final int CODE_SINGLE_QUOTE = '\'';
+ public static final int CODE_DOUBLE_QUOTE = '"';
+ public static final int CODE_QUESTION_MARK = '?';
+ public static final int CODE_EXCLAMATION_MARK = '!';
+ // TODO: Check how this should work for right-to-left languages. It seems to stand
+ // that for rtl languages, a closing parenthesis is a left parenthesis. Is this
+ // managed by the font? Or is it a different char?
+ public static final int CODE_CLOSING_PARENTHESIS = ')';
+ public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
+ public static final int CODE_CLOSING_CURLY_BRACKET = '}';
+ public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
+
+ /**
+ * Special keys code. Must be negative.
+ * These should be aligned with KeyboardCodesSet.ID_TO_NAME[],
+ * KeyboardCodesSet.DEFAULT[] and KeyboardCodesSet.RTL[]
+ */
+ public static final int CODE_SHIFT = -1;
+ public static final int CODE_SWITCH_ALPHA_SYMBOL = -2;
+ public static final int CODE_OUTPUT_TEXT = -3;
+ public static final int CODE_DELETE = -4;
+ public static final int CODE_SETTINGS = -5;
+ public static final int CODE_SHORTCUT = -6;
+ public static final int CODE_ACTION_ENTER = -7;
+ public static final int CODE_ACTION_NEXT = -8;
+ public static final int CODE_ACTION_PREVIOUS = -9;
+ public static final int CODE_LANGUAGE_SWITCH = -10;
+ public static final int CODE_RESEARCH = -11;
+ // Code value representing the code is not specified.
+ public static final int CODE_UNSPECIFIED = -12;
+
+ public static boolean isLetterCode(final int code) {
+ return code >= CODE_SPACE;
+ }
+
+ public static String printableCode(final int code) {
+ switch (code) {
+ case CODE_SHIFT: return "shift";
+ case CODE_SWITCH_ALPHA_SYMBOL: return "symbol";
+ case CODE_OUTPUT_TEXT: return "text";
+ case CODE_DELETE: return "delete";
+ case CODE_SETTINGS: return "settings";
+ case CODE_SHORTCUT: return "shortcut";
+ case CODE_ACTION_ENTER: return "actionEnter";
+ case CODE_ACTION_NEXT: return "actionNext";
+ case CODE_ACTION_PREVIOUS: return "actionPrevious";
+ case CODE_LANGUAGE_SWITCH: return "languageSwitch";
+ case CODE_UNSPECIFIED: return "unspec";
+ case CODE_TAB: return "tab";
+ case CODE_ENTER: return "enter";
+ default:
+ if (code <= 0) Log.w(TAG, "Unknown non-positive key code=" + code);
+ if (code < CODE_SPACE) return String.format("'\\u%02x'", code);
+ if (code < 0x100) return String.format("'%c'", code);
+ return String.format("'\\u%04x'", code);
+ }
+ }
+
private Constants() {
// This utility class is not publicly instantiable.
}
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 7c0448024..d1b32a2f3 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -24,8 +24,6 @@ import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.util.Log;
-import com.android.inputmethod.keyboard.Keyboard;
-
import java.util.Locale;
public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
@@ -194,7 +192,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
int cp = 0;
for (end = startIndex + 1; end < len; end += Character.charCount(cp)) {
cp = string.codePointAt(end);
- if (!(cp == Keyboard.CODE_DASH || cp == Keyboard.CODE_SINGLE_QUOTE
+ if (!(cp == Constants.CODE_DASH || cp == Constants.CODE_SINGLE_QUOTE
|| Character.isLetter(cp))) {
break;
}
diff --git a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
index c6a81033d..16cc1b35f 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableDictionary.java
@@ -19,7 +19,6 @@ package com.android.inputmethod.latin;
import android.content.Context;
import android.text.TextUtils;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.UserHistoryForgettingCurveUtils.ForgettingCurveParams;
@@ -472,8 +471,8 @@ public class ExpandableDictionary extends Dictionary {
getWordsRec(children, codes, word, depth + 1, true, snr, inputIndex,
skipPos, suggestions);
}
- } else if ((c == Keyboard.CODE_SINGLE_QUOTE
- && currentChars[0] != Keyboard.CODE_SINGLE_QUOTE) || depth == skipPos) {
+ } else if ((c == Constants.CODE_SINGLE_QUOTE
+ && currentChars[0] != Constants.CODE_SINGLE_QUOTE) || depth == skipPos) {
// Skip the ' and continue deeper
word[depth] = c;
if (children != null) {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 829b0c89d..c2afb1c4e 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1140,7 +1140,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
CharSequence lastTwo = mConnection.getTextBeforeCursor(2, 0);
// It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called.
if (lastTwo != null && lastTwo.length() == 2
- && lastTwo.charAt(0) == Keyboard.CODE_SPACE) {
+ && lastTwo.charAt(0) == Constants.CODE_SPACE) {
mConnection.deleteSurroundingText(2, 0);
mConnection.commitText(lastTwo.charAt(1) + " ", 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
@@ -1156,8 +1156,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final CharSequence lastThree = mConnection.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3
&& canBeFollowedByPeriod(lastThree.charAt(0))
- && lastThree.charAt(1) == Keyboard.CODE_SPACE
- && lastThree.charAt(2) == Keyboard.CODE_SPACE) {
+ && lastThree.charAt(1) == Constants.CODE_SPACE
+ && lastThree.charAt(2) == Constants.CODE_SPACE) {
mHandler.cancelDoubleSpacesTimer();
mConnection.deleteSurroundingText(2, 0);
mConnection.commitText(". ", 1);
@@ -1171,12 +1171,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// TODO: Check again whether there really ain't a better way to check this.
// TODO: This should probably be language-dependant...
return Character.isLetterOrDigit(codePoint)
- || codePoint == Keyboard.CODE_SINGLE_QUOTE
- || codePoint == Keyboard.CODE_DOUBLE_QUOTE
- || codePoint == Keyboard.CODE_CLOSING_PARENTHESIS
- || codePoint == Keyboard.CODE_CLOSING_SQUARE_BRACKET
- || codePoint == Keyboard.CODE_CLOSING_CURLY_BRACKET
- || codePoint == Keyboard.CODE_CLOSING_ANGLE_BRACKET;
+ || codePoint == Constants.CODE_SINGLE_QUOTE
+ || codePoint == Constants.CODE_DOUBLE_QUOTE
+ || codePoint == Constants.CODE_CLOSING_PARENTHESIS
+ || codePoint == Constants.CODE_CLOSING_SQUARE_BRACKET
+ || codePoint == Constants.CODE_CLOSING_CURLY_BRACKET
+ || codePoint == Constants.CODE_CLOSING_ANGLE_BRACKET;
}
// Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is
@@ -1271,7 +1271,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// 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
+ if (Constants.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
@@ -1288,7 +1288,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
@Override
public void onCodeInput(final int primaryCode, final int x, final int y) {
final long when = SystemClock.uptimeMillis();
- if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
+ if (primaryCode != Constants.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
mDeleteCount = 0;
}
mLastKeyTime = when;
@@ -1303,13 +1303,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (!mWordComposer.isComposingWord()) mIsAutoCorrectionIndicatorOn = false;
// TODO: Consolidate the double space timer, mLastKeyTime, and the space state.
- if (primaryCode != Keyboard.CODE_SPACE) {
+ if (primaryCode != Constants.CODE_SPACE) {
mHandler.cancelDoubleSpacesTimer();
}
boolean didAutoCorrect = false;
switch (primaryCode) {
- case Keyboard.CODE_DELETE:
+ case Constants.CODE_DELETE:
mSpaceState = SPACE_STATE_NONE;
handleBackspace(spaceState);
mDeleteCount++;
@@ -1317,29 +1317,29 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mShouldSwitchToLastSubtype = true;
LatinImeLogger.logOnDelete(x, y);
break;
- case Keyboard.CODE_SHIFT:
- case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
+ case Constants.CODE_SHIFT:
+ case Constants.CODE_SWITCH_ALPHA_SYMBOL:
// Shift and symbol key is handled in onPressKey() and onReleaseKey().
break;
- case Keyboard.CODE_SETTINGS:
+ case Constants.CODE_SETTINGS:
onSettingsKeyPressed();
break;
- case Keyboard.CODE_SHORTCUT:
+ case Constants.CODE_SHORTCUT:
mSubtypeSwitcher.switchToShortcutIME(this);
break;
- case Keyboard.CODE_ACTION_ENTER:
+ case Constants.CODE_ACTION_ENTER:
performEditorAction(getActionId(switcher.getKeyboard()));
break;
- case Keyboard.CODE_ACTION_NEXT:
+ case Constants.CODE_ACTION_NEXT:
performEditorAction(EditorInfo.IME_ACTION_NEXT);
break;
- case Keyboard.CODE_ACTION_PREVIOUS:
+ case Constants.CODE_ACTION_PREVIOUS:
performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
break;
- case Keyboard.CODE_LANGUAGE_SWITCH:
+ case Constants.CODE_LANGUAGE_SWITCH:
handleLanguageSwitchKey();
break;
- case Keyboard.CODE_RESEARCH:
+ case Constants.CODE_RESEARCH:
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.getInstance().onResearchKeySelected(this);
}
@@ -1375,10 +1375,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
switcher.onCodeInput(primaryCode);
// Reset after any single keystroke, except shift and symbol-shift
- if (!didAutoCorrect && primaryCode != Keyboard.CODE_SHIFT
- && primaryCode != Keyboard.CODE_SWITCH_ALPHA_SYMBOL)
+ if (!didAutoCorrect && primaryCode != Constants.CODE_SHIFT
+ && primaryCode != Constants.CODE_SWITCH_ALPHA_SYMBOL)
mLastComposedWord.deactivate();
- if (Keyboard.CODE_DELETE != primaryCode) {
+ if (Constants.CODE_DELETE != primaryCode) {
mEnteredText = null;
}
mConnection.endBatchEdit();
@@ -1399,14 +1399,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mHandler.postUpdateSuggestionStrip();
final String text = specificTldProcessingOnTextInput(rawText);
if (SPACE_STATE_PHANTOM == mSpaceState) {
- sendKeyCodePoint(Keyboard.CODE_SPACE);
+ sendKeyCodePoint(Constants.CODE_SPACE);
}
mConnection.commitText(text, 1);
mConnection.endBatchEdit();
// Space state must be updated before calling updateShiftState
mSpaceState = SPACE_STATE_NONE;
mKeyboardSwitcher.updateShiftState();
- mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
+ mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
mEnteredText = text;
}
@@ -1562,7 +1562,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mWordComposer.setBatchInputWord(batchInputText);
mConnection.beginBatchEdit();
if (SPACE_STATE_PHANTOM == mSpaceState) {
- sendKeyCodePoint(Keyboard.CODE_SPACE);
+ sendKeyCodePoint(Constants.CODE_SPACE);
}
mConnection.setComposingText(batchInputText, 1);
mExpectingUpdateSelection = true;
@@ -1573,7 +1573,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
private String specificTldProcessingOnTextInput(final String text) {
- if (text.length() <= 1 || text.charAt(0) != Keyboard.CODE_PERIOD
+ if (text.length() <= 1 || text.charAt(0) != Constants.CODE_PERIOD
|| !Character.isLetter(text.charAt(1))) {
// Not a tld: do nothing.
return text;
@@ -1584,7 +1584,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// TODO: use getCodePointBeforeCursor instead to improve performance and simplify the code
final CharSequence lastOne = mConnection.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
- && lastOne.charAt(0) == Keyboard.CODE_PERIOD) {
+ && lastOne.charAt(0) == Constants.CODE_PERIOD) {
return text.substring(1);
} else {
return text;
@@ -1689,7 +1689,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private boolean maybeStripSpace(final int code,
final int spaceState, final boolean isFromSuggestionStrip) {
- if (Keyboard.CODE_ENTER == code && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
+ if (Constants.CODE_ENTER == code && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
mConnection.removeTrailingSpace();
return false;
} else if ((SPACE_STATE_WEAK == spaceState
@@ -1718,7 +1718,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Sanity check
throw new RuntimeException("Should not be composing here");
}
- sendKeyCodePoint(Keyboard.CODE_SPACE);
+ sendKeyCodePoint(Constants.CODE_SPACE);
}
// NOTE: isCursorTouchingWord() is a blocking IPC call, so it often takes several
@@ -1732,7 +1732,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// the character is a single quote. The idea here is, single quote is not a
// separator and it should be treated as a normal character, except in the first
// position where it should not start composing a word.
- isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != primaryCode);
+ isComposingWord = (Constants.CODE_SINGLE_QUOTE != primaryCode);
// Here we don't need to reset the last composed word. It will be reset
// when we commit this one, if we ever do; if on the other hand we backspace
// it entirely and resume suggestions on the previous word, we'd like to still
@@ -1796,11 +1796,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (SPACE_STATE_PHANTOM == spaceState &&
mCurrentSettings.isPhantomSpacePromotingSymbol(primaryCode)) {
- sendKeyCodePoint(Keyboard.CODE_SPACE);
+ sendKeyCodePoint(Constants.CODE_SPACE);
}
sendKeyCodePoint(primaryCode);
- if (Keyboard.CODE_SPACE == primaryCode) {
+ if (Constants.CODE_SPACE == primaryCode) {
if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) {
if (maybeDoubleSpace()) {
mSpaceState = SPACE_STATE_DOUBLE;
@@ -2060,7 +2060,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
int firstChar = Character.codePointAt(suggestion, 0);
if ((!mCurrentSettings.isWeakSpaceStripper(firstChar))
&& (!mCurrentSettings.isWeakSpaceSwapper(firstChar))) {
- sendKeyCodePoint(Keyboard.CODE_SPACE);
+ sendKeyCodePoint(Constants.CODE_SPACE);
}
}
@@ -2105,7 +2105,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
&& !AutoCorrection.isValidWord(mSuggest.getUnigramDictionaries(), suggestion, true);
if (ProductionFlag.IS_INTERNAL) {
- Stats.onSeparator((char)Keyboard.CODE_SPACE,
+ Stats.onSeparator((char)Constants.CODE_SPACE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
}
if (showingAddToDictionaryHint && mIsUserDictionaryAvailable) {
@@ -2276,16 +2276,16 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// If accessibility is on, ensure the user receives keyboard state updates.
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
switch (primaryCode) {
- case Keyboard.CODE_SHIFT:
+ case Constants.CODE_SHIFT:
AccessibleKeyboardViewProxy.getInstance().notifyShiftState();
break;
- case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
+ case Constants.CODE_SWITCH_ALPHA_SYMBOL:
AccessibleKeyboardViewProxy.getInstance().notifySymbolsState();
break;
}
}
- if (Keyboard.CODE_DELETE == primaryCode) {
+ if (Constants.CODE_DELETE == primaryCode) {
// This is a stopgap solution to avoid leaving a high surrogate alone in a text view.
// In the future, we need to deprecate deteleSurroundingText() and have a surrogate
// pair-friendly way of deleting characters in InputConnection.
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index bf2dfbc0b..d1c96d42a 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -26,7 +26,6 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.research.ResearchLogger;
@@ -590,7 +589,7 @@ public final class RichInputConnection {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
final CharSequence lastOne = getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
- && lastOne.charAt(0) == Keyboard.CODE_SPACE) {
+ && lastOne.charAt(0) == Constants.CODE_SPACE) {
deleteSurroundingText(1, 0);
}
}
@@ -616,7 +615,7 @@ public final class RichInputConnection {
CharSequence word = getWordAtCursor(settings.mWordSeparators);
// We don't suggest on leading single quotes, so we have to remove them from the word if
// it starts with single quotes.
- while (!TextUtils.isEmpty(word) && Keyboard.CODE_SINGLE_QUOTE == word.charAt(0)) {
+ while (!TextUtils.isEmpty(word) && Constants.CODE_SINGLE_QUOTE == word.charAt(0)) {
word = word.subSequence(1, word.length());
}
if (TextUtils.isEmpty(word)) return null;
@@ -668,7 +667,7 @@ public final class RichInputConnection {
// NOTE: This does not work with surrogate pairs. Hopefully when the keyboard is able to
// enter surrogate pairs this code will have been removed.
if (TextUtils.isEmpty(textBeforeCursor)
- || (Keyboard.CODE_SPACE != textBeforeCursor.charAt(1))) {
+ || (Constants.CODE_SPACE != textBeforeCursor.charAt(1))) {
// We may only come here if the application is changing the text while we are typing.
// This is quite a broken case, but not logically impossible, so we shouldn't crash,
// but some debugging log may be in order.
diff --git a/java/src/com/android/inputmethod/latin/StringUtils.java b/java/src/com/android/inputmethod/latin/StringUtils.java
index 44b75b568..043043cef 100644
--- a/java/src/com/android/inputmethod/latin/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/StringUtils.java
@@ -19,9 +19,6 @@ package com.android.inputmethod.latin;
import android.text.InputType;
import android.text.TextUtils;
-//For character constants
-import com.android.inputmethod.keyboard.Keyboard;
-
import java.util.ArrayList;
import java.util.Locale;
@@ -175,7 +172,7 @@ public final class StringUtils {
} else {
for (i = cs.length(); i > 0; i--) {
final char c = cs.charAt(i - 1);
- if (c != Keyboard.CODE_DOUBLE_QUOTE && c != Keyboard.CODE_SINGLE_QUOTE
+ if (c != Constants.CODE_DOUBLE_QUOTE && c != Constants.CODE_SINGLE_QUOTE
&& Character.getType(c) != Character.START_PUNCTUATION) {
break;
}
@@ -191,11 +188,11 @@ public final class StringUtils {
// if the first char that's not a space or tab is a start of line (as in \n, start of text,
// or some other similar characters).
int j = i;
- char prevChar = Keyboard.CODE_SPACE;
+ char prevChar = Constants.CODE_SPACE;
if (hasSpaceBefore) --j;
while (j > 0) {
prevChar = cs.charAt(j - 1);
- if (!Character.isSpaceChar(prevChar) && prevChar != Keyboard.CODE_TAB) break;
+ if (!Character.isSpaceChar(prevChar) && prevChar != Constants.CODE_TAB) break;
j--;
}
if (j <= 0 || Character.isWhitespace(prevChar)) {
@@ -234,7 +231,7 @@ public final class StringUtils {
// variants of English, the final period is placed within double quotes and maybe
// other closing punctuation signs. This is generally not true in other languages.
final char c = cs.charAt(j - 1);
- if (c != Keyboard.CODE_DOUBLE_QUOTE && c != Keyboard.CODE_SINGLE_QUOTE
+ if (c != Constants.CODE_DOUBLE_QUOTE && c != Constants.CODE_SINGLE_QUOTE
&& Character.getType(c) != Character.END_PUNCTUATION) {
break;
}
@@ -248,10 +245,10 @@ public final class StringUtils {
// end of a sentence. If we have a question mark or an exclamation mark, it's the end of
// a sentence. If it's neither, the only remaining case is the period so we get the opposite
// case out of the way.
- if (c == Keyboard.CODE_QUESTION_MARK || c == Keyboard.CODE_EXCLAMATION_MARK) {
+ if (c == Constants.CODE_QUESTION_MARK || c == Constants.CODE_EXCLAMATION_MARK) {
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_SENTENCES) & reqModes;
}
- if (c != Keyboard.CODE_PERIOD || j <= 0) {
+ if (c != Constants.CODE_PERIOD || j <= 0) {
return (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes;
}
@@ -301,7 +298,7 @@ public final class StringUtils {
case WORD:
if (Character.isLetter(c)) {
state = WORD;
- } else if (c == Keyboard.CODE_PERIOD) {
+ } else if (c == Constants.CODE_PERIOD) {
state = PERIOD;
} else {
return caps;
@@ -317,7 +314,7 @@ public final class StringUtils {
case LETTER:
if (Character.isLetter(c)) {
state = LETTER;
- } else if (c == Keyboard.CODE_PERIOD) {
+ } else if (c == Constants.CODE_PERIOD) {
state = PERIOD;
} else {
return noCaps;
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index c87161bd3..3dc2ba95b 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -20,7 +20,6 @@ import android.content.Context;
import android.text.TextUtils;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -392,7 +391,7 @@ public final class Suggest {
sb.append(wordInfo.mWord);
}
for (int i = trailingSingleQuotesCount - 1; i >= 0; --i) {
- sb.appendCodePoint(Keyboard.CODE_SINGLE_QUOTE);
+ sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE);
}
return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKind,
wordInfo.mSourceDict);
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index 229aa8a48..daff442f3 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -135,7 +135,7 @@ public final class WordComposer {
mTypedWord.appendCodePoint(primaryCode);
refreshSize();
if (newIndex < BinaryDictionary.MAX_WORD_LENGTH) {
- mPrimaryKeyCodes[newIndex] = primaryCode >= Keyboard.CODE_SPACE
+ mPrimaryKeyCodes[newIndex] = primaryCode >= Constants.CODE_SPACE
? Character.toLowerCase(primaryCode) : primaryCode;
// In the batch input mode, the {@code mInputPointers} holds batch input points and
// shouldn't be overridden by the "typed key" coordinates
@@ -149,7 +149,7 @@ public final class WordComposer {
newIndex, primaryCode, mIsFirstCharCapitalized);
if (Character.isUpperCase(primaryCode)) mCapsCount++;
if (Character.isDigit(primaryCode)) mDigitsCount++;
- if (Keyboard.CODE_SINGLE_QUOTE == primaryCode) {
+ if (Constants.CODE_SINGLE_QUOTE == primaryCode) {
++mTrailingSingleQuotesCount;
} else {
mTrailingSingleQuotesCount = 0;
@@ -236,7 +236,7 @@ public final class WordComposer {
int i = mTypedWord.length();
while (i > 0) {
i = mTypedWord.offsetByCodePoints(i, -1);
- if (Keyboard.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break;
+ if (Constants.CODE_SINGLE_QUOTE != mTypedWord.codePointAt(i)) break;
++mTrailingSingleQuotesCount;
}
}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 763fd6e00..6295abe8c 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -870,7 +870,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final long time = SystemClock.uptimeMillis();
final ResearchLogger researchLogger = getInstance();
final Object[] values = {
- Keyboard.printableCode(scrubDigitFromCodePoint(code)), x, y
+ Constants.printableCode(scrubDigitFromCodePoint(code)), x, y
};
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_ONCODEINPUT, values);
if (Character.isDigit(code)) {
@@ -1006,7 +1006,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
};
public static void latinIME_sendKeyCodePoint(final int code) {
final Object[] values = {
- Keyboard.printableCode(scrubDigitFromCodePoint(code))
+ Constants.printableCode(scrubDigitFromCodePoint(code))
};
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_SENDKEYCODEPOINT, values);
@@ -1092,7 +1092,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
if (key != null) {
String outputText = key.getOutputText();
final Object[] values = {
- Keyboard.printableCode(scrubDigitFromCodePoint(code)), outputText == null ? null
+ Constants.printableCode(scrubDigitFromCodePoint(code)), outputText == null ? null
: scrubDigitsFromString(outputText.toString()),
x, y, ignoreModifierKey, altersCode, key.isEnabled()
};
@@ -1109,7 +1109,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final boolean withSliding, final boolean ignoreModifierKey) {
if (key != null) {
final Object[] values = {
- Keyboard.printableCode(scrubDigitFromCodePoint(primaryCode)), withSliding,
+ Constants.printableCode(scrubDigitFromCodePoint(primaryCode)), withSliding,
ignoreModifierKey, key.isEnabled()
};
getInstance().enqueuePotentiallyPrivateEvent(
diff --git a/java/src/com/android/inputmethod/research/Statistics.java b/java/src/com/android/inputmethod/research/Statistics.java
index eab465aa2..98491bd23 100644
--- a/java/src/com/android/inputmethod/research/Statistics.java
+++ b/java/src/com/android/inputmethod/research/Statistics.java
@@ -16,7 +16,7 @@
package com.android.inputmethod.research;
-import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.Constants;
public class Statistics {
// Number of characters entered during a typing session
@@ -104,7 +104,7 @@ public class Statistics {
public void recordChar(int codePoint, long time) {
final long delta = time - mLastTapTime;
- if (codePoint == Keyboard.CODE_DELETE) {
+ if (codePoint == Constants.CODE_DELETE) {
mDeleteKeyCount++;
if (delta < MIN_DELETION_INTERMISSION) {
if (mIsLastKeyDeleteKey) {
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
index 1ab577557..5bba961bd 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeySpecParserTests.java
@@ -16,13 +16,13 @@
package com.android.inputmethod.keyboard.internal;
-import static com.android.inputmethod.keyboard.Keyboard.CODE_OUTPUT_TEXT;
-import static com.android.inputmethod.keyboard.Keyboard.CODE_UNSPECIFIED;
import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
+import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
+import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
import android.test.AndroidTestCase;
-import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.Constants;
import java.util.Arrays;
import java.util.Locale;
@@ -69,8 +69,8 @@ public class KeySpecParserTests extends AndroidTestCase {
KeyboardIconsSet.getIconName(expectedIcon),
KeyboardIconsSet.getIconName(spec.mIconId));
assertEquals(message + " [code]",
- Keyboard.printableCode(expectedCode),
- Keyboard.printableCode(spec.mCode));
+ Constants.printableCode(expectedCode),
+ Constants.printableCode(spec.mCode));
}
private void assertParserError(String message, String moreKeySpec, String expectedLabel,
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
index 2770ed54a..c75f8269a 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/KeyboardStateTestsBase.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard.internal;
import android.test.AndroidTestCase;
public class KeyboardStateTestsBase extends AndroidTestCase
- implements MockKeyboardSwitcher.Constants {
+ implements MockKeyboardSwitcher.MockConstants {
protected MockKeyboardSwitcher mSwitcher;
private String mLayoutSwitchBackSymbols = "";
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
index dd4caadf1..0213744fb 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MockKeyboardSwitcher.java
@@ -18,25 +18,24 @@ package com.android.inputmethod.keyboard.internal;
import android.text.TextUtils;
-import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.latin.Constants;
public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
- public interface Constants {
+ public interface MockConstants {
// Argument for {@link KeyboardState#onPressKey} and {@link KeyboardState#onReleaseKey}.
public static final boolean NOT_SLIDING = false;
public static final boolean SLIDING = true;
// Argument for {@link KeyboardState#onCodeInput}.
public static final boolean SINGLE = true;
public static final boolean MULTI = false;
- public static final int CAP_MODE_OFF =
- com.android.inputmethod.latin.Constants.TextUtils.CAP_MODE_OFF;
+ public static final int CAP_MODE_OFF = Constants.TextUtils.CAP_MODE_OFF;
public static final int CAP_MODE_WORDS = TextUtils.CAP_MODE_WORDS;
public static final int CAP_MODE_CHARACTERS = TextUtils.CAP_MODE_CHARACTERS;
- public static final int CODE_SHIFT = Keyboard.CODE_SHIFT;
- public static final int CODE_SYMBOL = Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
- public static final int CODE_SPACE = Keyboard.CODE_SPACE;
- public static final int CODE_AUTO_CAPS_TRIGGER = Keyboard.CODE_SPACE;
+ public static final int CODE_SHIFT = Constants.CODE_SHIFT;
+ public static final int CODE_SYMBOL = Constants.CODE_SWITCH_ALPHA_SYMBOL;
+ public static final int CODE_SPACE = Constants.CODE_SPACE;
+ public static final int CODE_AUTO_CAPS_TRIGGER = Constants.CODE_SPACE;
public static final int ALPHABET_UNSHIFTED = 0;
public static final int ALPHABET_MANUAL_SHIFTED = 1;
@@ -47,11 +46,11 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
public static final int SYMBOLS_SHIFTED = 6;
}
- private int mLayout = Constants.ALPHABET_UNSHIFTED;
+ private int mLayout = MockConstants.ALPHABET_UNSHIFTED;
- private int mAutoCapsMode = Constants.CAP_MODE_OFF;
+ private int mAutoCapsMode = MockConstants.CAP_MODE_OFF;
// Following InputConnection's behavior. Simulating InputType.TYPE_TEXT_FLAG_CAP_WORDS.
- private int mAutoCapsState = Constants.CAP_MODE_OFF;
+ private int mAutoCapsState = MockConstants.CAP_MODE_OFF;
private boolean mIsInDoubleTapTimeout;
private int mLongPressTimeoutCode;
@@ -64,13 +63,13 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
public static String getLayoutName(int layoutId) {
switch (layoutId) {
- case Constants.ALPHABET_UNSHIFTED: return "ALPHABET_UNSHIFTED";
- case Constants.ALPHABET_MANUAL_SHIFTED: return "ALPHABET_MANUAL_SHIFTED";
- case Constants.ALPHABET_AUTOMATIC_SHIFTED: return "ALPHABET_AUTOMATIC_SHIFTED";
- case Constants.ALPHABET_SHIFT_LOCKED: return "ALPHABET_SHIFT_LOCKED";
- case Constants.ALPHABET_SHIFT_LOCK_SHIFTED: return "ALPHABET_SHIFT_LOCK_SHIFTED";
- case Constants.SYMBOLS_UNSHIFTED: return "SYMBOLS_UNSHIFTED";
- case Constants.SYMBOLS_SHIFTED: return "SYMBOLS_SHIFTED";
+ case MockConstants.ALPHABET_UNSHIFTED: return "ALPHABET_UNSHIFTED";
+ case MockConstants.ALPHABET_MANUAL_SHIFTED: return "ALPHABET_MANUAL_SHIFTED";
+ case MockConstants.ALPHABET_AUTOMATIC_SHIFTED: return "ALPHABET_AUTOMATIC_SHIFTED";
+ case MockConstants.ALPHABET_SHIFT_LOCKED: return "ALPHABET_SHIFT_LOCKED";
+ case MockConstants.ALPHABET_SHIFT_LOCK_SHIFTED: return "ALPHABET_SHIFT_LOCK_SHIFTED";
+ case MockConstants.SYMBOLS_UNSHIFTED: return "SYMBOLS_UNSHIFTED";
+ case MockConstants.SYMBOLS_SHIFTED: return "SYMBOLS_SHIFTED";
default: return "UNKNOWN<" + layoutId + ">";
}
}
@@ -86,37 +85,37 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
@Override
public void setAlphabetKeyboard() {
- mLayout = Constants.ALPHABET_UNSHIFTED;
+ mLayout = MockConstants.ALPHABET_UNSHIFTED;
}
@Override
public void setAlphabetManualShiftedKeyboard() {
- mLayout = Constants.ALPHABET_MANUAL_SHIFTED;
+ mLayout = MockConstants.ALPHABET_MANUAL_SHIFTED;
}
@Override
public void setAlphabetAutomaticShiftedKeyboard() {
- mLayout = Constants.ALPHABET_AUTOMATIC_SHIFTED;
+ mLayout = MockConstants.ALPHABET_AUTOMATIC_SHIFTED;
}
@Override
public void setAlphabetShiftLockedKeyboard() {
- mLayout = Constants.ALPHABET_SHIFT_LOCKED;
+ mLayout = MockConstants.ALPHABET_SHIFT_LOCKED;
}
@Override
public void setAlphabetShiftLockShiftedKeyboard() {
- mLayout = Constants.ALPHABET_SHIFT_LOCK_SHIFTED;
+ mLayout = MockConstants.ALPHABET_SHIFT_LOCK_SHIFTED;
}
@Override
public void setSymbolsKeyboard() {
- mLayout = Constants.SYMBOLS_UNSHIFTED;
+ mLayout = MockConstants.SYMBOLS_UNSHIFTED;
}
@Override
public void setSymbolsShiftedKeyboard() {
- mLayout = Constants.SYMBOLS_SHIFTED;
+ mLayout = MockConstants.SYMBOLS_SHIFTED;
}
@Override
@@ -186,10 +185,10 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
}
public void onCodeInput(int code, boolean isSinglePointer) {
- if (mAutoCapsMode == Constants.CAP_MODE_WORDS) {
- if (Keyboard.isLetterCode(code)) {
- mAutoCapsState = (code == Constants.CODE_AUTO_CAPS_TRIGGER)
- ? mAutoCapsMode : Constants.CAP_MODE_OFF;
+ if (mAutoCapsMode == MockConstants.CAP_MODE_WORDS) {
+ if (Constants.isLetterCode(code)) {
+ mAutoCapsState = (code == MockConstants.CODE_AUTO_CAPS_TRIGGER)
+ ? mAutoCapsMode : MockConstants.CAP_MODE_OFF;
}
} else {
mAutoCapsState = mAutoCapsMode;
diff --git a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
index 2544bd87c..02047cfc4 100644
--- a/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
+++ b/tests/src/com/android/inputmethod/latin/BlueUnderlineTests.java
@@ -16,8 +16,6 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.keyboard.Keyboard;
-
import android.text.style.SuggestionSpan;
import android.text.style.UnderlineSpan;
@@ -67,13 +65,13 @@ public class BlueUnderlineTests extends InputTestsBase {
type(STRING_TO_TYPE);
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
- type(Keyboard.CODE_SPACE);
+ type(Constants.CODE_SPACE);
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
sleep(DELAY_TO_WAIT_FOR_UNDERLINE);
runMessages();
final SpanGetter suggestionSpan = new SpanGetter(mTextView.getText(), SuggestionSpan.class);
diff --git a/tests/src/com/android/inputmethod/latin/InputLogicTests.java b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
index 3b9eda212..38f5305de 100644
--- a/tests/src/com/android/inputmethod/latin/InputLogicTests.java
+++ b/tests/src/com/android/inputmethod/latin/InputLogicTests.java
@@ -16,8 +16,6 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.keyboard.Keyboard;
-
public class InputLogicTests extends InputTestsBase {
public void testTypeWord() {
@@ -32,7 +30,7 @@ public class InputLogicTests extends InputTestsBase {
type(WORD_TO_TYPE);
pickSuggestionManually(0, WORD_TO_TYPE);
mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("press suggestion then backspace", EXPECTED_RESULT,
mTextView.getText().toString());
}
@@ -48,7 +46,7 @@ public class InputLogicTests extends InputTestsBase {
mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
assertEquals("pick typed word over auto-correction then backspace", WORD_TO_PICK,
mTextView.getText().toString());
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("pick typed word over auto-correction then backspace", EXPECTED_RESULT,
mTextView.getText().toString());
}
@@ -63,7 +61,7 @@ public class InputLogicTests extends InputTestsBase {
mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
assertEquals("pick typed word over auto-correction then backspace", WORD_TO_TYPE,
mTextView.getText().toString());
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("pick typed word over auto-correction then backspace", EXPECTED_RESULT,
mTextView.getText().toString());
}
@@ -79,7 +77,7 @@ public class InputLogicTests extends InputTestsBase {
mLatinIME.onUpdateSelection(0, 0, WORD_TO_TYPE.length(), WORD_TO_TYPE.length(), -1, -1);
assertEquals("pick different suggestion then backspace", WORD_TO_PICK,
mTextView.getText().toString());
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("pick different suggestion then backspace", EXPECTED_RESULT,
mTextView.getText().toString());
}
@@ -100,7 +98,7 @@ public class InputLogicTests extends InputTestsBase {
// And now we simulate the user actually selecting some text.
mLatinIME.onUpdateSelection(typedLength, typedLength,
SELECTION_START, SELECTION_END, -1, -1);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("delete selection", EXPECTED_RESULT, mTextView.getText().toString());
}
@@ -123,7 +121,7 @@ public class InputLogicTests extends InputTestsBase {
final String EXPECTED_RESULT = "tgis.";
type(STRING_TO_TYPE);
mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("auto-correct with period then revert", EXPECTED_RESULT,
mTextView.getText().toString());
}
@@ -133,7 +131,7 @@ public class InputLogicTests extends InputTestsBase {
final String EXPECTED_RESULT = "tgis ";
type(STRING_TO_TYPE);
mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("auto-correct with space then revert", EXPECTED_RESULT,
mTextView.getText().toString());
}
@@ -143,7 +141,7 @@ public class InputLogicTests extends InputTestsBase {
final String EXPECTED_RESULT = "this";
type(STRING_TO_TYPE);
mLatinIME.onUpdateSelection(0, 0, STRING_TO_TYPE.length(), STRING_TO_TYPE.length(), -1, -1);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("auto-correct with space does not revert", EXPECTED_RESULT,
mTextView.getText().toString());
}
@@ -159,7 +157,7 @@ public class InputLogicTests extends InputTestsBase {
final String STRING_TO_TYPE = "this ";
final String EXPECTED_RESULT = "this ";
type(STRING_TO_TYPE);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("double space make a period", EXPECTED_RESULT, mTextView.getText().toString());
}
@@ -173,7 +171,7 @@ public class InputLogicTests extends InputTestsBase {
mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
mLatinIME.onUpdateSelection(typedLength, typedLength,
NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("auto correct then move cursor to start of line then backspace",
EXPECTED_RESULT, mTextView.getText().toString());
}
@@ -188,7 +186,7 @@ public class InputLogicTests extends InputTestsBase {
mInputConnection.setSelection(NEW_CURSOR_POSITION, NEW_CURSOR_POSITION);
mLatinIME.onUpdateSelection(typedLength, typedLength,
NEW_CURSOR_POSITION, NEW_CURSOR_POSITION, -1, -1);
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
assertEquals("auto correct then move cursor then backspace",
EXPECTED_RESULT, mTextView.getText().toString());
}
@@ -264,7 +262,7 @@ public class InputLogicTests extends InputTestsBase {
final String WORD_TO_TYPE = "this";
type(WORD_TO_TYPE);
for (int i = 0; i < WORD_TO_TYPE.length(); ++i) {
- type(Keyboard.CODE_DELETE);
+ type(Constants.CODE_DELETE);
}
assertEquals("delete whole composing word", "", mTextView.getText().toString());
}
--
cgit v1.2.3-83-g751a
From cfbfb1c50a18234c5415a9897f62b0d456036885 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Mon, 29 Oct 2012 17:25:13 +0900
Subject: Remove reference of android.util.Log in Constants class
This is a follow up of Iee01d4d2.
Change-Id: I0bcd349d317d9f7d40ef0574e72c640f9f990c5d
---
java/src/com/android/inputmethod/latin/Constants.java | 4 ----
1 file changed, 4 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index d10ed8efb..fa6ff1848 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -16,11 +16,8 @@
package com.android.inputmethod.latin;
-import android.util.Log;
public final class Constants {
- private static final String TAG = Constants.class.getSimpleName();
-
public static final class Color {
/**
* The alpha value for fully opaque.
@@ -204,7 +201,6 @@ public final class Constants {
case CODE_TAB: return "tab";
case CODE_ENTER: return "enter";
default:
- if (code <= 0) Log.w(TAG, "Unknown non-positive key code=" + code);
if (code < CODE_SPACE) return String.format("'\\u%02x'", code);
if (code < 0x100) return String.format("'%c'", code);
return String.format("'\\u%04x'", code);
--
cgit v1.2.3-83-g751a
From c7318bbc0b47662799d2f7a01e5b53edb43ebf2a Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka"
Date: Mon, 29 Oct 2012 18:40:37 +0900
Subject: Fix possible NPE
Bug: 7398904
Change-Id: I6b7aba7a9bf52ca494cb4390b19525c98790bd49
---
java/src/com/android/inputmethod/latin/LatinIME.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index c2afb1c4e..c66ff9504 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1932,7 +1932,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private SuggestedWords getSuggestedWords(final int sessionId) {
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
- if (keyboard == null) {
+ if (keyboard == null || mSuggest == null) {
return SuggestedWords.EMPTY;
}
final String typedWord = mWordComposer.getTypedWord();
--
cgit v1.2.3-83-g751a
From 51a0ef8c59ea590b6e5e80a82fc75bf244084270 Mon Sep 17 00:00:00 2001
From: Jean Chalard
Date: Wed, 31 Oct 2012 15:35:20 +0900
Subject: Add a plumbing option to dicttool info.
Also align the `porcelain' option to the diff command
that was used mistakenly.
Bug: 7388665
Change-Id: Ic0e1b98c62ce37b2e909384a0370af4458563703
---
.../latin/makedict/FusionDictionary.java | 14 +++++++++-----
.../android/inputmethod/latin/dicttool/Diff.java | 10 +++++-----
.../android/inputmethod/latin/dicttool/Info.java | 22 +++++++++++++++++-----
3 files changed, 31 insertions(+), 15 deletions(-)
(limited to 'java/src/com/android/inputmethod/latin')
diff --git a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
index c588824fe..b0b3777df 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FusionDictionary.java
@@ -290,19 +290,23 @@ public final class FusionDictionary implements Iterable {
}
@Override
public String toString() { // Convenience method
- return toString(0);
+ return toString(0, false);
}
- public String toString(final int indentCount) {
+ public String toString(final int indentCount, final boolean plumbing) {
final StringBuilder indent = new StringBuilder();
- for (int i = 0; i < indentCount; ++i) {
- indent.append(" ");
+ if (plumbing) {
+ indent.append("H:");
+ } else {
+ for (int i = 0; i < indentCount; ++i) {
+ indent.append(" ");
+ }
}
final StringBuilder s = new StringBuilder();
for (final String optionKey : mAttributes.keySet()) {
s.append(indent);
s.append(optionKey);
s.append(" = ");
- if ("date".equals(optionKey)) {
+ if ("date".equals(optionKey) && !plumbing) {
// Date needs a number of milliseconds, but the dictionary contains seconds
s.append(new Date(
1000 * Long.parseLong(mAttributes.get(optionKey))).toString());
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
index 9548f2509..855c026b9 100644
--- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
+++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/Diff.java
@@ -34,7 +34,7 @@ public class Diff extends Dicttool.Command {
@Override
public String getHelp() {
return COMMAND + " [-p]