diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java | 103 |
1 files changed, 41 insertions, 62 deletions
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java index 09d0ea210..96160fa4e 100644 --- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java @@ -29,10 +29,13 @@ import android.provider.ContactsContract.Contacts; import android.text.TextUtils; import android.util.Log; +import com.android.inputmethod.annotations.UsedForTesting; import com.android.inputmethod.latin.personalization.AccountUtils; +import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.StringUtils; import java.io.File; +import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -59,10 +62,10 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { private static final int INDEX_NAME = 1; /** The number of contacts in the most recent dictionary rebuild. */ - static private int sContactCountAtLastRebuild = 0; + private int mContactCountAtLastRebuild = 0; - /** The locale for this contacts dictionary. Controls name bigram predictions. */ - public final Locale mLocale; + /** The hash code of ArrayList of contacts names in the most recent dictionary rebuild. */ + private int mHashCodeAtLastRebuild = 0; private ContentObserver mObserver; @@ -71,25 +74,21 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { */ private final boolean mUseFirstLastBigrams; - public ContactsBinaryDictionary(final Context context, final Locale locale) { - this(context, locale, null /* dictFile */); - } - - public ContactsBinaryDictionary(final Context context, final Locale locale, - final File dictFile) { - this(context, locale, dictFile, NAME); - } - protected ContactsBinaryDictionary(final Context context, final Locale locale, final File dictFile, final String name) { super(context, getDictName(name, locale, dictFile), locale, Dictionary.TYPE_CONTACTS, dictFile); - mLocale = locale; mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale); registerObserver(context); reloadDictionaryIfRequired(); } + @UsedForTesting + public static ContactsBinaryDictionary getDictionary(final Context context, final Locale locale, + final File dictFile, final String dictNamePrefix) { + return new ContactsBinaryDictionary(context, locale, dictFile, dictNamePrefix + NAME); + } + private synchronized void registerObserver(final Context context) { if (mObserver != null) return; ContentResolver cres = context.getContentResolver(); @@ -97,7 +96,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { new ContentObserver(null) { @Override public void onChange(boolean self) { - setNeedsToReload(); + ExecutorUtils.getExecutor("Check Contacts").execute(new Runnable() { + @Override + public void run() { + if (haveContentsChanged()) { + setNeedsToRecreate(); + } + } + }); } }); } @@ -130,7 +136,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { Log.d(TAG, "loadAccountVocabulary: " + word); } runGCIfRequiredLocked(true /* mindsBlockByGC */); - addWordDynamicallyLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */, + addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); } @@ -144,7 +150,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { return; } if (cursor.moveToFirst()) { - sContactCountAtLastRebuild = getContactCount(); + mContactCountAtLastRebuild = getContactCount(); addWordsLocked(cursor); } } catch (final SQLiteException e) { @@ -168,9 +174,11 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { private void addWordsLocked(final Cursor cursor) { int count = 0; + final ArrayList<String> names = new ArrayList<>(); while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) { String name = cursor.getString(INDEX_NAME); if (isValidName(name)) { + names.add(name); addNameLocked(name); ++count; } else { @@ -180,6 +188,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { } cursor.moveToNext(); } + mHashCodeAtLastRebuild = names.hashCode(); } private int getContactCount() { @@ -209,7 +218,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { */ private void addNameLocked(final String name) { int len = StringUtils.codePointCount(name); - String prevWord = null; + PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO; // TODO: Better tokenization for non-Latin writing systems for (int i = 0; i < len; i++) { if (Character.isLetter(name.codePointAt(i))) { @@ -224,19 +233,19 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { final int wordLen = StringUtils.codePointCount(word); if (wordLen < MAX_WORD_LENGTH && wordLen > 1) { if (DEBUG) { - Log.d(TAG, "addName " + name + ", " + word + ", " + prevWord); + Log.d(TAG, "addName " + name + ", " + word + ", " + + prevWordsInfo.mPrevWord); } runGCIfRequiredLocked(true /* mindsBlockByGC */); - addWordDynamicallyLocked(word, FREQUENCY_FOR_CONTACTS, + addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP); - if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) { + if (!TextUtils.isEmpty(prevWordsInfo.mPrevWord) && mUseFirstLastBigrams) { runGCIfRequiredLocked(true /* mindsBlockByGC */); - addBigramDynamicallyLocked(prevWord, word, - FREQUENCY_FOR_CONTACTS_BIGRAM, + addNgramEntryLocked(prevWordsInfo, word, FREQUENCY_FOR_CONTACTS_BIGRAM, BinaryDictionary.NOT_A_VALID_TIMESTAMP); } - prevWord = word; + prevWordsInfo = new PrevWordsInfo(word); } } } @@ -259,8 +268,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { return end; } - @Override - protected boolean haveContentsChanged() { + private boolean haveContentsChanged() { final long startTime = SystemClock.uptimeMillis(); final int contactCount = getContactCount(); if (contactCount > MAX_CONTACT_COUNT) { @@ -269,9 +277,9 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { // TODO: Sort and check only the MAX_CONTACT_COUNT most recent contacts? return false; } - if (contactCount != sContactCountAtLastRebuild) { + if (contactCount != mContactCountAtLastRebuild) { if (DEBUG) { - Log.d(TAG, "Contact count changed: " + sContactCountAtLastRebuild + " to " + Log.d(TAG, "Contact count changed: " + mContactCountAtLastRebuild + " to " + contactCount); } return true; @@ -284,20 +292,20 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { if (null == cursor) { return false; } + final ArrayList<String> names = new ArrayList<>(); try { if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { String name = cursor.getString(INDEX_NAME); - if (isValidName(name) && !isNameInDictionaryLocked(name)) { - if (DEBUG) { - Log.d(TAG, "Contact name missing: " + name + " (runtime = " - + (SystemClock.uptimeMillis() - startTime) + " ms)"); - } - return true; + if (isValidName(name)) { + names.add(name); } cursor.moveToNext(); } } + if (names.hashCode() != mHashCodeAtLastRebuild) { + return true; + } } finally { cursor.close(); } @@ -314,33 +322,4 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { } return false; } - - /** - * Checks if the words in a name are in the current binary dictionary. - */ - private boolean isNameInDictionaryLocked(final String name) { - int len = StringUtils.codePointCount(name); - String prevWord = null; - for (int i = 0; i < len; i++) { - if (Character.isLetter(name.codePointAt(i))) { - int end = getWordEndPosition(name, len, i); - String word = name.substring(i, end); - i = end - 1; - final int wordLen = StringUtils.codePointCount(word); - if (wordLen < MAX_WORD_LENGTH && wordLen > 1) { - if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) { - if (!isValidBigramLocked(prevWord, word)) { - return false; - } - } else { - if (!isValidWordLocked(word)) { - return false; - } - } - prevWord = word; - } - } - } - return true; - } } |