aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/src/com/android/inputmethod/deprecated/VoiceProxy.java17
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java24
-rw-r--r--native/src/bigram_dictionary.cpp2
-rw-r--r--native/src/binary_format.h47
-rw-r--r--native/src/defines.h3
-rw-r--r--native/src/dictionary.cpp14
-rw-r--r--native/src/unigram_dictionary.cpp3
-rw-r--r--tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java44
8 files changed, 97 insertions, 57 deletions
diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
index 700709d50..c1c6d31cd 100644
--- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
+++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java
@@ -92,6 +92,7 @@ public class VoiceProxy implements VoiceInput.UiListener {
private static final boolean DEBUG = LatinImeLogger.sDBG;
private boolean mAfterVoiceInput;
+ private boolean mConfigurationChanging;
private boolean mHasUsedVoiceInput;
private boolean mHasUsedVoiceInputUnsupportedLocale;
private boolean mImmediatelyAfterVoiceInput;
@@ -159,11 +160,11 @@ public class VoiceProxy implements VoiceInput.UiListener {
mPasswordText = isPasswordText;
}
- public void flushVoiceInputLogs(boolean configurationChanged) {
+ public void flushVoiceInputLogs() {
if (!VOICE_INSTALLED) {
return;
}
- if (!configurationChanged) {
+ if (!mConfigurationChanging) {
if (mAfterVoiceInput) {
mVoiceInput.flushAllTextModificationCounters();
mVoiceInput.logInputEnded();
@@ -318,11 +319,11 @@ public class VoiceProxy implements VoiceInput.UiListener {
mImmediatelyAfterVoiceInput = false;
}
- public void hideVoiceWindow(boolean configurationChanging) {
+ public void hideVoiceWindow() {
if (!VOICE_INSTALLED) {
return;
}
- if (!configurationChanging) {
+ if (!mConfigurationChanging) {
if (mAfterVoiceInput)
mVoiceInput.logInputEnded();
if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) {
@@ -842,4 +843,12 @@ public class VoiceProxy implements VoiceInput.UiListener {
SettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES,
DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES);
}
+
+ public void startChangingConfiguration() {
+ mConfigurationChanging = true;
+ }
+
+ public void finishChangingConfiguration() {
+ mConfigurationChanging = false;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index cb22b4935..cb2a275e8 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -195,8 +195,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
- private KeyboardSwitcher mKeyboardSwitcher;
- private SubtypeSwitcher mSubtypeSwitcher;
+ private final KeyboardSwitcher mKeyboardSwitcher;
+ private final SubtypeSwitcher mSubtypeSwitcher;
private VoiceProxy mVoiceProxy;
private boolean mShouldSwitchToLastSubtype = true;
@@ -226,9 +226,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
private VibratorCompatWrapper mVibrator;
- // TODO: Move this flag to VoiceProxy
- private boolean mConfigurationChanging;
-
// Member variables for remembering the current device orientation.
private int mDisplayOrientation;
@@ -492,6 +489,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
}
}
+ public LatinIME() {
+ super();
+ mSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ mKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ }
+
@Override
public void onCreate() {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -506,8 +509,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
super.onCreate();
mImm = InputMethodManagerCompatWrapper.getInstance();
- mSubtypeSwitcher = SubtypeSwitcher.getInstance();
- mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mVibrator = VibratorCompatWrapper.getInstance(this);
mHandler.onCreate();
DEBUG = LatinImeLogger.sDBG;
@@ -555,7 +556,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
// Has to be package-visible for unit tests
/* package */ void loadSettings() {
if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- if (null == mSubtypeSwitcher) mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mSettingsValues = new SettingsValues(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr());
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
}
@@ -667,10 +667,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mOptionsDialog.dismiss();
}
- mConfigurationChanging = true;
+ mVoiceProxy.startChangingConfiguration();
super.onConfigurationChanged(conf);
mVoiceProxy.onConfigurationChanged(conf);
- mConfigurationChanging = false;
+ mVoiceProxy.finishChangingConfiguration();
// This will work only when the subtype is not supported.
LanguageSwitcherProxy.onConfigurationChanged(conf);
@@ -833,7 +833,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
LatinImeLogger.commit();
- mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging);
+ mVoiceProxy.flushVoiceInputLogs();
KeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
if (inputView != null) inputView.closing();
@@ -963,7 +963,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mOptionsDialog.dismiss();
mOptionsDialog = null;
}
- mVoiceProxy.hideVoiceWindow(mConfigurationChanging);
+ mVoiceProxy.hideVoiceWindow();
super.hideWindow();
}
diff --git a/native/src/bigram_dictionary.cpp b/native/src/bigram_dictionary.cpp
index 19b644679..84048d77d 100644
--- a/native/src/bigram_dictionary.cpp
+++ b/native/src/bigram_dictionary.cpp
@@ -28,7 +28,7 @@ namespace latinime {
BigramDictionary::BigramDictionary(const unsigned char *dict, int maxWordLength,
int maxAlternatives, const bool isLatestDictVersion, const bool hasBigram,
Dictionary *parentDictionary)
- : DICT(dict + NEW_DICTIONARY_HEADER_SIZE), MAX_WORD_LENGTH(maxWordLength),
+ : DICT(dict), MAX_WORD_LENGTH(maxWordLength),
MAX_ALTERNATIVES(maxAlternatives), IS_LATEST_DICT_VERSION(isLatestDictVersion),
HAS_BIGRAM(hasBigram), mParentDictionary(parentDictionary) {
if (DEBUG_DICT) {
diff --git a/native/src/binary_format.h b/native/src/binary_format.h
index 1d74998f6..ab033ad90 100644
--- a/native/src/binary_format.h
+++ b/native/src/binary_format.h
@@ -17,6 +17,7 @@
#ifndef LATINIME_BINARY_FORMAT_H
#define LATINIME_BINARY_FORMAT_H
+#include <limits>
#include "unigram_dictionary.h"
namespace latinime {
@@ -29,10 +30,18 @@ class BinaryFormat {
public:
const static int UNKNOWN_FORMAT = -1;
- const static int FORMAT_VERSION_1 = 1;
- const static uint16_t FORMAT_VERSION_1_MAGIC_NUMBER = 0x78B1;
+ // Originally, format version 1 had a 16-bit magic number, then the version number `01'
+ // then options that must be 0. Hence the first 32-bits of the format are always as follow
+ // and it's okay to consider them a magic number as a whole.
+ const static uint32_t FORMAT_VERSION_1_MAGIC_NUMBER = 0x78B10100;
+ const static unsigned int FORMAT_VERSION_1_HEADER_SIZE = 5;
+ // The versions of Latin IME that only handle format version 1 only test for the magic
+ // number, so we had to change it so that version 2 files would be rejected by older
+ // implementations. On this occasion, we made the magic number 32 bits long.
+ const static uint32_t FORMAT_VERSION_2_MAGIC_NUMBER = 0x9BC13AFE;
static int detectFormat(const uint8_t* const dict);
+ static unsigned int getHeaderSize(const uint8_t* const dict);
static int getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos);
static uint8_t getFlagsAndForwardPointer(const uint8_t* const dict, int* pos);
static int32_t getCharCodeAndForwardPointer(const uint8_t* const dict, int* pos);
@@ -55,9 +64,37 @@ class BinaryFormat {
};
inline int BinaryFormat::detectFormat(const uint8_t* const dict) {
- const uint16_t magicNumber = (dict[0] << 8) + dict[1]; // big endian
- if (FORMAT_VERSION_1_MAGIC_NUMBER == magicNumber) return FORMAT_VERSION_1;
- return UNKNOWN_FORMAT;
+ // The magic number is stored big-endian.
+ const uint32_t magicNumber = (dict[0] << 24) + (dict[1] << 16) + (dict[2] << 8) + dict[3];
+ switch (magicNumber) {
+ case FORMAT_VERSION_1_MAGIC_NUMBER:
+ // Format 1 header is exactly 5 bytes long and looks like:
+ // Magic number (2 bytes) 0x78 0xB1
+ // Version number (1 byte) 0x01
+ // Options (2 bytes) must be 0x00 0x00
+ return 1;
+ case FORMAT_VERSION_2_MAGIC_NUMBER:
+ // Format 2 header is as follows:
+ // Magic number (4 bytes) 0x9B 0xC1 0x3A 0xFE
+ // Version number (2 bytes) 0x00 0x02
+ // Options (2 bytes) must be 0x00 0x00
+ // Header size (4 bytes) : integer, big endian
+ return (dict[4] << 8) + dict[5];
+ default:
+ return UNKNOWN_FORMAT;
+ }
+}
+
+inline unsigned int BinaryFormat::getHeaderSize(const uint8_t* const dict) {
+ switch (detectFormat(dict)) {
+ case 1:
+ return FORMAT_VERSION_1_HEADER_SIZE;
+ case 2:
+ // See the format of the header in the comment in detectFormat() above
+ return (dict[8] << 24) + (dict[9] << 16) + (dict[10] << 8) + dict[11];
+ default:
+ return std::numeric_limits<unsigned int>::max();
+ }
}
inline int BinaryFormat::getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos) {
diff --git a/native/src/defines.h b/native/src/defines.h
index f402efa8d..afa1e0404 100644
--- a/native/src/defines.h
+++ b/native/src/defines.h
@@ -162,9 +162,6 @@ static inline void prof_out(void) {
#define FLAG_BIGRAM_FREQ 0x7F
#define DICTIONARY_VERSION_MIN 200
-// TODO: remove this constant when the switch to the new dict format is over
-#define DICTIONARY_HEADER_SIZE 2
-#define NEW_DICTIONARY_HEADER_SIZE 5
#define NOT_VALID_WORD -99
#define NOT_A_CHARACTER -1
#define NOT_A_DISTANCE -1
diff --git a/native/src/dictionary.cpp b/native/src/dictionary.cpp
index 822c2151d..8e252f730 100644
--- a/native/src/dictionary.cpp
+++ b/native/src/dictionary.cpp
@@ -19,6 +19,7 @@
#define LOG_TAG "LatinIME: dictionary.cpp"
+#include "binary_format.h"
#include "dictionary.h"
namespace latinime {
@@ -41,10 +42,11 @@ Dictionary::Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust,
mCorrection = new Correction(typedLetterMultiplier, fullWordMultiplier);
mWordsPriorityQueuePool = new WordsPriorityQueuePool(
maxWords, SUB_QUEUE_MAX_WORDS, maxWordLength);
- mUnigramDictionary = new UnigramDictionary(mDict, typedLetterMultiplier, fullWordMultiplier,
- maxWordLength, maxWords, maxAlternatives, IS_LATEST_DICT_VERSION);
- mBigramDictionary = new BigramDictionary(mDict, maxWordLength, maxAlternatives,
- IS_LATEST_DICT_VERSION, hasBigram(), this);
+ const unsigned int headerSize = BinaryFormat::getHeaderSize(mDict);
+ mUnigramDictionary = new UnigramDictionary(mDict + headerSize, typedLetterMultiplier,
+ fullWordMultiplier, maxWordLength, maxWords, maxAlternatives, IS_LATEST_DICT_VERSION);
+ mBigramDictionary = new BigramDictionary(mDict + headerSize, maxWordLength, maxAlternatives,
+ IS_LATEST_DICT_VERSION, true /* hasBigram */, this);
}
Dictionary::~Dictionary() {
@@ -54,10 +56,6 @@ Dictionary::~Dictionary() {
delete mBigramDictionary;
}
-bool Dictionary::hasBigram() {
- return ((mDict[1] & 0xFF) == 1);
-}
-
bool Dictionary::isValidWord(unsigned short *word, int length) {
return mUnigramDictionary->isValidWord(word, length);
}
diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp
index 155bdcb7a..0b646d1cd 100644
--- a/native/src/unigram_dictionary.cpp
+++ b/native/src/unigram_dictionary.cpp
@@ -38,8 +38,7 @@ const UnigramDictionary::digraph_t UnigramDictionary::GERMAN_UMLAUT_DIGRAPHS[] =
UnigramDictionary::UnigramDictionary(const uint8_t* const streamStart, int typedLetterMultiplier,
int fullWordMultiplier, int maxWordLength, int maxWords, int maxProximityChars,
const bool isLatestDictVersion)
- : DICT_ROOT(streamStart + NEW_DICTIONARY_HEADER_SIZE),
- MAX_WORD_LENGTH(maxWordLength), MAX_WORDS(maxWords),
+ : DICT_ROOT(streamStart), MAX_WORD_LENGTH(maxWordLength), MAX_WORDS(maxWords),
MAX_PROXIMITY_CHARS(maxProximityChars), IS_LATEST_DICT_VERSION(isLatestDictVersion),
TYPED_LETTER_MULTIPLIER(typedLetterMultiplier), FULL_WORD_MULTIPLIER(fullWordMultiplier),
// TODO : remove this variable.
diff --git a/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java b/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java
index 937e76c1e..485dba10b 100644
--- a/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java
+++ b/tools/makedict/src/com/android/inputmethod/latin/BinaryDictInputOutput.java
@@ -115,6 +115,7 @@ public class BinaryDictInputOutput {
private static final int VERSION_2_MAGIC_NUMBER = 0x9BC13AFE;
private static final int MINIMUM_SUPPORTED_VERSION = 1;
private static final int MAXIMUM_SUPPORTED_VERSION = 2;
+ private static final int NOT_A_VERSION_NUMBER = -1;
private static final int FIRST_VERSION_WITH_HEADER_SIZE = 2;
// No options yet, reserved for future use.
@@ -829,24 +830,28 @@ public class BinaryDictInputOutput {
buffer[index++] = (byte) (0xFF & (VERSION_2_MAGIC_NUMBER >> 16));
buffer[index++] = (byte) (0xFF & (VERSION_2_MAGIC_NUMBER >> 8));
buffer[index++] = (byte) (0xFF & VERSION_2_MAGIC_NUMBER);
+ // Dictionary version.
+ buffer[index++] = (byte) (0xFF & (version >> 8));
+ buffer[index++] = (byte) (0xFF & version);
} else {
// Magic number for version 1.
buffer[index++] = (byte) (0xFF & (VERSION_1_MAGIC_NUMBER >> 8));
buffer[index++] = (byte) (0xFF & VERSION_1_MAGIC_NUMBER);
+ // Dictionary version.
+ buffer[index++] = (byte) (0xFF & version);
}
- // Dictionary version.
- buffer[index++] = (byte) (0xFF & version);
// Options flags
buffer[index++] = (byte) (0xFF & (OPTIONS >> 8));
buffer[index++] = (byte) (0xFF & OPTIONS);
if (version >= FIRST_VERSION_WITH_HEADER_SIZE) {
final int headerSizeOffset = index;
- index += 3; // Size of the header size
+ index += 4; // Size of the header size
// TODO: Write out the header contents here.
// Write out the header size.
- buffer[headerSizeOffset] = (byte) (0xFF & (index >> 16));
- buffer[headerSizeOffset + 1] = (byte) (0xFF & (index >> 8));
- buffer[headerSizeOffset + 2] = (byte) (0xFF & (index >> 0));
+ buffer[headerSizeOffset] = (byte) (0xFF & (index >> 24));
+ buffer[headerSizeOffset + 1] = (byte) (0xFF & (index >> 16));
+ buffer[headerSizeOffset + 2] = (byte) (0xFF & (index >> 8));
+ buffer[headerSizeOffset + 3] = (byte) (0xFF & (index >> 0));
}
destination.write(buffer, 0, index);
@@ -1122,14 +1127,14 @@ public class BinaryDictInputOutput {
}
/**
- * Helper function to test the magic number of the file.
+ * Helper function to get the binary format version from the header.
*/
- private static boolean isExpectedMagicNumber(final RandomAccessFile source) throws IOException {
+ private static int getFormatVersion(final RandomAccessFile source) throws IOException {
final int magic_v1 = source.readUnsignedShort();
- if (VERSION_1_MAGIC_NUMBER == magic_v1) return true;
+ if (VERSION_1_MAGIC_NUMBER == magic_v1) return source.readUnsignedByte();
final int magic_v2 = (magic_v1 << 16) + source.readUnsignedShort();
- if (VERSION_2_MAGIC_NUMBER == magic_v2) return true;
- return false;
+ if (VERSION_2_MAGIC_NUMBER == magic_v2) return source.readUnsignedShort();
+ return NOT_A_VERSION_NUMBER;
}
/**
@@ -1145,15 +1150,9 @@ public class BinaryDictInputOutput {
*/
public static FusionDictionary readDictionaryBinary(final RandomAccessFile source,
final FusionDictionary dict) throws IOException, UnsupportedFormatException {
- // Check magic number
- if (!isExpectedMagicNumber(source)) {
- throw new UnsupportedFormatException("The magic number in this file does not match "
- + "the expected value");
- }
-
// Check file version
- final int version = source.readUnsignedByte();
- if (version > MAXIMUM_SUPPORTED_VERSION) {
+ final int version = getFormatVersion(source);
+ if (version < MINIMUM_SUPPORTED_VERSION || version > MAXIMUM_SUPPORTED_VERSION ) {
throw new UnsupportedFormatException("This file has version " + version
+ ", but this implementation does not support versions above "
+ MAXIMUM_SUPPORTED_VERSION);
@@ -1166,8 +1165,8 @@ public class BinaryDictInputOutput {
if (version < FIRST_VERSION_WITH_HEADER_SIZE) {
headerSize = source.getFilePointer();
} else {
- headerSize = (source.readUnsignedByte() << 16) + (source.readUnsignedByte() << 8)
- + source.readUnsignedByte();
+ headerSize = (source.readUnsignedByte() << 24) + (source.readUnsignedByte() << 16)
+ + (source.readUnsignedByte() << 8) + source.readUnsignedByte();
// read the header body
source.seek(headerSize);
}
@@ -1198,7 +1197,8 @@ public class BinaryDictInputOutput {
public static boolean isBinaryDictionary(final String filename) {
try {
RandomAccessFile f = new RandomAccessFile(filename, "r");
- return isExpectedMagicNumber(f);
+ final int version = getFormatVersion(f);
+ return (version >= MINIMUM_SUPPORTED_VERSION && version <= MAXIMUM_SUPPORTED_VERSION);
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {