diff options
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 8 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/UserDictionary.java | 22 | ||||
-rw-r--r-- | native/src/unigram_dictionary.cpp | 34 | ||||
-rw-r--r-- | native/src/unigram_dictionary.h | 1 |
4 files changed, 42 insertions, 23 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1b9983a6e..324a13045 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -151,6 +151,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private UserDictionary mUserDictionary; private UserBigramDictionary mUserBigramDictionary; private UserUnigramDictionary mUserUnigramDictionary; + private boolean mIsUserDictionaryAvaliable; // TODO: Create an inner class to group options and pseudo-options to improve readability. // These variables are initialized according to the {@link EditorInfo#inputType}. @@ -436,6 +437,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mUserDictionary = new UserDictionary(this, localeStr); mSuggest.setUserDictionary(mUserDictionary); + mIsUserDictionaryAvaliable = mUserDictionary.isEnabled(); resetContactsDictionary(); @@ -1689,7 +1691,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // take a noticeable delay to update them which may feel uneasy. } if (showingAddToDictionaryHint) { - mCandidateView.showAddToDictionaryHint(suggestion); + if (mIsUserDictionaryAvaliable) { + mCandidateView.showAddToDictionaryHint(suggestion); + } else { + mHandler.postUpdateSuggestions(); + } } if (ic != null) { ic.endBatchEdit(); diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java index 2aaa26c8d..f93d24fe6 100644 --- a/java/src/com/android/inputmethod/latin/UserDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserDictionary.java @@ -38,23 +38,24 @@ public class UserDictionary extends ExpandableDictionary { Words.FREQUENCY, Words.LOCALE, }; - + private ContentObserver mObserver; private String mLocale; public UserDictionary(Context context, String locale) { super(context, Suggest.DIC_USER); mLocale = locale; - // Perform a managed query. The Activity will handle closing and requerying the cursor + // Perform a managed query. The Activity will handle closing and re-querying the cursor // when needed. ContentResolver cres = context.getContentResolver(); - - cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) { + + mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { setRequiresReload(true); } - }); + }; + cres.registerContentObserver(Words.CONTENT_URI, true, mObserver); loadDictionary(); } @@ -76,6 +77,17 @@ public class UserDictionary extends ExpandableDictionary { addWords(cursor); } + public boolean isEnabled() { + final ContentResolver cr = getContext().getContentResolver(); + final ContentProviderClient client = cr.acquireContentProviderClient(Words.CONTENT_URI); + if (client != null) { + client.release(); + return true; + } else { + return false; + } + } + /** * Adds a word to the dictionary and makes it persistent. * @param word the word to add. If the word is capitalized, then the dictionary will diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp index afa8bc545..64d41f32e 100644 --- a/native/src/unigram_dictionary.cpp +++ b/native/src/unigram_dictionary.cpp @@ -1056,30 +1056,30 @@ int UnigramDictionary::getMostFrequentWordLikeInner(const uint16_t * const inWor } // This function gets the frequency of the exact matching word in the dictionary. -// If no match is found, it returns -1. -int UnigramDictionary::getFrequency(const uint16_t* const inWord, const int length) const { +// If no match is found, it returns NOT_VALID_WORD. +static inline int getFrequency(const uint8_t* const root, const uint16_t* const inWord, + const int length) { int pos = 0; int wordPos = 0; - const uint8_t* const root = DICT_ROOT; while (true) { // If we already traversed the tree further than the word is long, there means // there was no match (or we would have found it). - if (wordPos > length) return -1; + if (wordPos > length) return NOT_VALID_WORD; int charGroupCount = BinaryFormat::getGroupCountAndForwardPointer(root, &pos); const uint16_t wChar = inWord[wordPos]; while (true) { // If there are no more character groups in this node, it means we could not // find a matching character for this depth, therefore there is no match. - if (0 >= charGroupCount) return -1; + if (0 >= charGroupCount) return NOT_VALID_WORD; const uint8_t flags = BinaryFormat::getFlagsAndForwardPointer(root, &pos); int32_t character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos); if (character == wChar) { // This is the correct node. Only one character group may start with the same // char within a node, so either we found our match in this node, or there is - // no match and we can return -1. So we will check all the characters in this - // character group indeed does match. - if (FLAG_HAS_MULTIPLE_CHARS & flags) { + // no match and we can return NOT_VALID_WORD. So we will check all the characters + // in this character group indeed does match. + if (UnigramDictionary::FLAG_HAS_MULTIPLE_CHARS & flags) { character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos); while (NOT_A_CHARACTER != character) { ++wordPos; @@ -1087,8 +1087,8 @@ int UnigramDictionary::getFrequency(const uint16_t* const inWord, const int leng // character that does not match, as explained above, it means the word is // not in the dictionary (by virtue of this chargroup being the only one to // match the word on the first character, but not matching the whole word). - if (wordPos > length) return -1; - if (inWord[wordPos] != character) return -1; + if (wordPos > length) return NOT_VALID_WORD; + if (inWord[wordPos] != character) return NOT_VALID_WORD; character = BinaryFormat::getCharCodeAndForwardPointer(root, &pos); } } @@ -1097,14 +1097,16 @@ int UnigramDictionary::getFrequency(const uint16_t* const inWord, const int leng // If we don't match the length AND don't have children, then a word in the // dictionary fully matches a prefix of the searched word but not the full word. ++wordPos; - if (FLAG_IS_TERMINAL & flags) { + if (UnigramDictionary::FLAG_IS_TERMINAL & flags) { if (wordPos == length) { return BinaryFormat::readFrequencyWithoutMovingPointer(root, pos); } - pos = BinaryFormat::skipFrequency(FLAG_IS_TERMINAL, pos); + pos = BinaryFormat::skipFrequency(UnigramDictionary::FLAG_IS_TERMINAL, pos); + } + if (UnigramDictionary::FLAG_GROUP_ADDRESS_TYPE_NOADDRESS + == (UnigramDictionary::MASK_GROUP_ADDRESS_TYPE & flags)) { + return NOT_VALID_WORD; } - if (FLAG_GROUP_ADDRESS_TYPE_NOADDRESS == (MASK_GROUP_ADDRESS_TYPE & flags)) - return -1; // We have children and we are still shorter than the word we are searching for, so // we need to traverse children. Put the pointer on the children position, and // break @@ -1112,7 +1114,7 @@ int UnigramDictionary::getFrequency(const uint16_t* const inWord, const int leng break; } else { // This chargroup does not match, so skip the remaining part and go to the next. - if (FLAG_HAS_MULTIPLE_CHARS & flags) { + if (UnigramDictionary::FLAG_HAS_MULTIPLE_CHARS & flags) { pos = BinaryFormat::skipOtherCharacters(root, pos); } pos = BinaryFormat::skipFrequency(flags, pos); @@ -1124,7 +1126,7 @@ int UnigramDictionary::getFrequency(const uint16_t* const inWord, const int leng } bool UnigramDictionary::isValidWord(const uint16_t* const inWord, const int length) const { - return -1 != getFrequency(inWord, length); + return NOT_VALID_WORD != getFrequency(DICT_ROOT, inWord, length); } int UnigramDictionary::getBigrams(unsigned short *word, int length, int *codes, int codesSize, diff --git a/native/src/unigram_dictionary.h b/native/src/unigram_dictionary.h index f6045c6ef..55771eeb8 100644 --- a/native/src/unigram_dictionary.h +++ b/native/src/unigram_dictionary.h @@ -135,7 +135,6 @@ private: const int startInputIndex, const int depth, unsigned short *word, int *newChildPosition, int *newCount, bool *newTerminal, int *newFreq, int *siblingPos); #else // NEW_DICTIONARY_FORMAT - int getFrequency(const uint16_t* const inWord, const int length) const; int getMostFrequentWordLikeInner(const uint16_t* const inWord, const int length, short unsigned int* outWord); #endif // NEW_DICTIONARY_FORMAT |