Check whether contacts have changed using hashCode().
Bug: 13755213 Change-Id: Ie2f7b7f9dc8bd3fce395618877d9f234287dcb21main
parent
04348c3637
commit
9898ee6267
|
@ -31,9 +31,12 @@ import android.util.Log;
|
|||
|
||||
import com.android.inputmethod.annotations.UsedForTesting;
|
||||
import com.android.inputmethod.latin.personalization.AccountUtils;
|
||||
import com.android.inputmethod.latin.utils.CollectionUtils;
|
||||
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;
|
||||
|
||||
|
@ -60,7 +63,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 hash code of ArrayList of contacts names in the most recent dictionary rebuild. */
|
||||
private int mHashCodeAtLastRebuild = 0;
|
||||
|
||||
private ContentObserver mObserver;
|
||||
|
||||
|
@ -96,7 +102,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();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -143,7 +156,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
|||
return;
|
||||
}
|
||||
if (cursor.moveToFirst()) {
|
||||
sContactCountAtLastRebuild = getContactCount();
|
||||
mContactCountAtLastRebuild = getContactCount();
|
||||
addWordsLocked(cursor);
|
||||
}
|
||||
} catch (final SQLiteException e) {
|
||||
|
@ -167,9 +180,11 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
|||
|
||||
private void addWordsLocked(final Cursor cursor) {
|
||||
int count = 0;
|
||||
final ArrayList<String> names = CollectionUtils.newArrayList();
|
||||
while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) {
|
||||
String name = cursor.getString(INDEX_NAME);
|
||||
if (isValidName(name)) {
|
||||
names.add(name);
|
||||
addNameLocked(name);
|
||||
++count;
|
||||
} else {
|
||||
|
@ -179,6 +194,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
|||
}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
mHashCodeAtLastRebuild = names.hashCode();
|
||||
}
|
||||
|
||||
private int getContactCount() {
|
||||
|
@ -258,8 +274,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) {
|
||||
|
@ -268,9 +283,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;
|
||||
|
@ -283,20 +298,20 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
|
|||
if (null == cursor) {
|
||||
return false;
|
||||
}
|
||||
final ArrayList<String> names = CollectionUtils.newArrayList();
|
||||
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();
|
||||
}
|
||||
|
@ -313,33 +328,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,8 +92,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
/** Indicates whether a task for reloading the dictionary has been scheduled. */
|
||||
private final AtomicBoolean mIsReloading;
|
||||
|
||||
/** Indicates whether the current dictionary needs to be reloaded. */
|
||||
private boolean mNeedsToReload;
|
||||
/** Indicates whether the current dictionary needs to be recreated. */
|
||||
private boolean mNeedsToRecreate;
|
||||
|
||||
private final ReentrantReadWriteLock mLock;
|
||||
|
||||
|
@ -107,13 +107,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
*/
|
||||
protected abstract void loadInitialContentsLocked();
|
||||
|
||||
/**
|
||||
* Indicates that the source dictionary contents have changed and a rebuild of the binary file
|
||||
* is required. If it returns false, the next reload will only read the current binary
|
||||
* dictionary from file.
|
||||
*/
|
||||
protected abstract boolean haveContentsChanged();
|
||||
|
||||
private boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
|
||||
return formatVersion == FormatSpec.VERSION4;
|
||||
}
|
||||
|
@ -147,7 +140,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
mDictFile = getDictFile(context, dictName, dictFile);
|
||||
mBinaryDictionary = null;
|
||||
mIsReloading = new AtomicBoolean();
|
||||
mNeedsToReload = false;
|
||||
mNeedsToRecreate = false;
|
||||
mLock = new ReentrantReadWriteLock();
|
||||
}
|
||||
|
||||
|
@ -486,11 +479,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
}
|
||||
|
||||
/**
|
||||
* Marks that the dictionary needs to be reloaded.
|
||||
* Marks that the dictionary needs to be recreated.
|
||||
*
|
||||
*/
|
||||
protected void setNeedsToReload() {
|
||||
mNeedsToReload = true;
|
||||
protected void setNeedsToRecreate() {
|
||||
mNeedsToRecreate = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -508,7 +501,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
* Returns whether a dictionary reload is required.
|
||||
*/
|
||||
private boolean isReloadRequired() {
|
||||
return mBinaryDictionary == null || mNeedsToReload;
|
||||
return mBinaryDictionary == null || mNeedsToRecreate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -520,8 +513,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// TODO: Quit checking contents in ExpandableBinaryDictionary.
|
||||
if (!mDictFile.exists() || (mNeedsToReload && haveContentsChanged())) {
|
||||
if (!mDictFile.exists() || mNeedsToRecreate) {
|
||||
// If the dictionary file does not exist or contents have been updated,
|
||||
// generate a new one.
|
||||
createNewDictionaryLocked();
|
||||
|
@ -533,12 +525,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
|
|||
&& matchesExpectedBinaryDictFormatVersionForThisType(
|
||||
mBinaryDictionary.getFormatVersion()))) {
|
||||
// Binary dictionary or its format version is not valid. Regenerate
|
||||
// the dictionary file. writeBinaryDictionary will remove the
|
||||
// the dictionary file. createNewDictionaryLocked will remove the
|
||||
// existing files if appropriate.
|
||||
createNewDictionaryLocked();
|
||||
}
|
||||
}
|
||||
mNeedsToReload = false;
|
||||
mNeedsToRecreate = false;
|
||||
} finally {
|
||||
mIsReloading.set(false);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
|||
// devices. On older versions of the platform, the hook above will be called instead.
|
||||
@Override
|
||||
public void onChange(final boolean self, final Uri uri) {
|
||||
setNeedsToReload();
|
||||
setNeedsToRecreate();
|
||||
}
|
||||
};
|
||||
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
|
||||
|
@ -272,9 +272,4 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean haveContentsChanged() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,11 +73,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
|
|||
return attributeMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean haveContentsChanged() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadInitialContentsLocked() {
|
||||
// No initial contents.
|
||||
|
|
Loading…
Reference in New Issue