Loading java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -89,8 +89,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { registerObserver(context); registerObserver(context); // Load the current binary dictionary from internal storage. If no binary dictionary exists, // Load the current binary dictionary from internal storage. If no binary dictionary exists, // loadDictionary will start a new thread to generate one asynchronously. // reloadDictionaryIfRequired will start a new thread to generate one asynchronously. loadDictionary(); reloadDictionaryIfRequired(); } } private synchronized void registerObserver(final Context context) { private synchronized void registerObserver(final Context context) { Loading @@ -100,7 +100,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { new ContentObserver(null) { new ContentObserver(null) { @Override @Override public void onChange(boolean self) { public void onChange(boolean self) { setRequiresReload(true); setNeedsToReload(); } } }); }); } } Loading java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +16 −102 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.AsyncResultHolder; import com.android.inputmethod.latin.utils.AsyncResultHolder; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.FileUtils; import com.android.inputmethod.latin.utils.FileUtils; Loading @@ -38,7 +37,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.Locale; import java.util.Locale; import java.util.Map; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -74,15 +72,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4; private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4; /** * A static map of update controllers, each of which records the time of accesses to a single * binary dictionary file and tracks whether the file is regenerating. The key for this map is * the dictionary name and the value is the shared dictionary time recorder associated with * that dictionary name. */ private static final ConcurrentHashMap<String, DictionaryUpdateController> sDictNameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap(); /** The application context. */ /** The application context. */ protected final Context mContext; protected final Context mContext; Loading @@ -105,14 +94,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** Dictionary file */ /** Dictionary file */ private final File mDictFile; private final File mDictFile; // TODO: remove, once dynamic operations is serialized private final AtomicBoolean mProcessingLargeTask; /** Controls updating the shared binary dictionary file across multiple instances. */ private boolean mNeedsToReload; private final DictionaryUpdateController mDictNameDictionaryUpdateController; // TODO: remove, once dynamic operations is serialized /** Controls updating the local binary dictionary for this instance. */ private final DictionaryUpdateController mPerInstanceDictionaryUpdateController = new DictionaryUpdateController(); /* A extension for a binary dictionary file. */ /* A extension for a binary dictionary file. */ protected static final String DICT_FILE_EXTENSION = ".dict"; protected static final String DICT_FILE_EXTENSION = ".dict"; Loading Loading @@ -145,21 +129,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return mBinaryDictionary.isValidDictionary(); return mBinaryDictionary.isValidDictionary(); } } /** * Gets the dictionary update controller for the given dictionary name. */ private static DictionaryUpdateController getDictionaryUpdateController( final String dictName) { DictionaryUpdateController recorder = sDictNameDictionaryUpdateControllerMap.get(dictName); if (recorder == null) { synchronized(sDictNameDictionaryUpdateControllerMap) { recorder = new DictionaryUpdateController(); sDictNameDictionaryUpdateControllerMap.put(dictName, recorder); } } return recorder; } /** /** * Creates a new expandable binary dictionary. * Creates a new expandable binary dictionary. * * Loading @@ -179,7 +148,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { mLocale = locale; mLocale = locale; mDictFile = getDictFile(context, dictName, dictFile); mDictFile = getDictFile(context, dictName, dictFile); mBinaryDictionary = null; mBinaryDictionary = null; mDictNameDictionaryUpdateController = getDictionaryUpdateController(dictName); mProcessingLargeTask = new AtomicBoolean(); mNeedsToReload = false; } } public static File getDictFile(final Context context, final String dictName, public static File getDictFile(final Context context, final String dictName, Loading Loading @@ -286,7 +256,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { try { try { mBinaryDictionary.flushWithGC(); mBinaryDictionary.flushWithGC(); } finally { } finally { mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false); mProcessingLargeTask.set(false); } } } } }); }); Loading Loading @@ -388,7 +358,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { callback.onFinished(); callback.onFinished(); } } if (locked) { if (locked) { mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false); mProcessingLargeTask.set(false); } } } } } } Loading Loading @@ -461,25 +431,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return mBinaryDictionary.isValidBigram(word1, word2); return mBinaryDictionary.isValidBigram(word1, word2); } } /** * Load the current binary dictionary from internal storage in a background thread. If no binary * dictionary exists, this method will generate one. */ protected void loadDictionary() { mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = System.currentTimeMillis(); reloadDictionaryIfRequired(); } /** /** * Loads the current binary dictionary from internal storage. Assumes the dictionary file * Loads the current binary dictionary from internal storage. Assumes the dictionary file * exists. * exists. */ */ private void loadBinaryDictionaryLocked() { private void loadBinaryDictionaryLocked() { if (DEBUG) { Log.d(TAG, "Loading binary dictionary: " + mDictName + " request=" + mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update=" + mDictNameDictionaryUpdateController.mLastUpdateTime); } if (DBG_STRESS_TEST) { if (DBG_STRESS_TEST) { // Test if this class does not cause problems when it takes long time to load binary // Test if this class does not cause problems when it takes long time to load binary // dictionary. // dictionary. Loading @@ -505,11 +461,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * Create a new binary dictionary and load initial contents. * Create a new binary dictionary and load initial contents. */ */ private void createNewDictionaryLocked() { private void createNewDictionaryLocked() { if (DEBUG) { Log.d(TAG, "Generating binary dictionary: " + mDictName + " request=" + mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update=" + mDictNameDictionaryUpdateController.mLastUpdateTime); } removeBinaryDictionaryLocked(); removeBinaryDictionaryLocked(); createOnMemoryBinaryDictionaryLocked(); createOnMemoryBinaryDictionaryLocked(); loadInitialContentsLocked(); loadInitialContentsLocked(); Loading @@ -529,20 +480,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } } /** /** * Marks that the dictionary is out of date and requires a reload. * Marks that the dictionary needs to be reloaded. * * * @param requiresRebuild Indicates that the source dictionary content has changed and a rebuild * of the binary file is required. If not true, the next reload process will only read * the current binary dictionary from file. */ */ protected void setRequiresReload(final boolean requiresRebuild) { protected void setNeedsToReload() { final long time = System.currentTimeMillis(); mNeedsToReload = true; mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = time; mDictNameDictionaryUpdateController.mLastUpdateRequestTime = time; if (DEBUG) { Log.d(TAG, "Reload request: " + mDictName + ": request=" + time + " update=" + mDictNameDictionaryUpdateController.mLastUpdateTime); } } } /** /** Loading @@ -559,18 +501,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * Returns whether a dictionary reload is required. * Returns whether a dictionary reload is required. */ */ private boolean isReloadRequired() { private boolean isReloadRequired() { return mBinaryDictionary == null || mPerInstanceDictionaryUpdateController.isOutOfDate(); return mBinaryDictionary == null || mNeedsToReload; } } private boolean processingLargeTask() { private boolean processingLargeTask() { return mDictNameDictionaryUpdateController.mProcessingLargeTask.get(); return mProcessingLargeTask.get(); } } // Returns whether the dictionary is being used for a large task. If true, we should not use // Returns whether the dictionary is being used for a large task. If true, we should not use // this dictionary for latency sensitive operations. // this dictionary for latency sensitive operations. private boolean setProcessingLargeTaskIfNot() { private boolean setProcessingLargeTaskIfNot() { return mDictNameDictionaryUpdateController.mProcessingLargeTask.compareAndSet( return mProcessingLargeTask.compareAndSet(false /* expect */ , true /* update */); false /* expect */ , true /* update */); } } /** /** Loading @@ -584,28 +525,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { @Override @Override public void run() { public void run() { try { try { final long time = System.currentTimeMillis(); if (!dictionaryFileExists() || haveContentsChanged()) { final boolean openedDictIsOutOfDate = mDictNameDictionaryUpdateController.isOutOfDate(); if (!dictionaryFileExists() || (openedDictIsOutOfDate && haveContentsChanged())) { // If the shared dictionary file does not exist or is out of date and // If the shared dictionary file does not exist or is out of date and // contents have been updated, the first instance that acquires the lock // contents have been updated, the first instance that acquires the lock // will generate a new one // will generate a new one mDictNameDictionaryUpdateController.mLastUpdateTime = time; createNewDictionaryLocked(); createNewDictionaryLocked(); } else if (openedDictIsOutOfDate) { } else if (mBinaryDictionary == null) { // If not, the reload request was unnecessary so revert // LastUpdateRequestTime to LastUpdateTime. mDictNameDictionaryUpdateController.mLastUpdateRequestTime = mDictNameDictionaryUpdateController.mLastUpdateTime; } else if (mBinaryDictionary == null || mPerInstanceDictionaryUpdateController.mLastUpdateTime < mDictNameDictionaryUpdateController.mLastUpdateTime) { // Otherwise, if the local dictionary is older than the shared dictionary, // Otherwise, if the local dictionary is older than the shared dictionary, // load the shared dictionary. // load the shared dictionary. loadBinaryDictionaryLocked(); loadBinaryDictionaryLocked(); } } mNeedsToReload = false; if (mBinaryDictionary != null && !(isValidDictionaryLocked() if (mBinaryDictionary != null && !(isValidDictionaryLocked() // TODO: remove the check below // TODO: remove the check below && matchesExpectedBinaryDictFormatVersionForThisType( && matchesExpectedBinaryDictFormatVersionForThisType( Loading @@ -613,12 +543,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { // Binary dictionary or its format version is not valid. Regenerate // Binary dictionary or its format version is not valid. Regenerate // the dictionary file. writeBinaryDictionary will remove the // the dictionary file. writeBinaryDictionary will remove the // existing files if appropriate. // existing files if appropriate. mDictNameDictionaryUpdateController.mLastUpdateTime = time; createNewDictionaryLocked(); createNewDictionaryLocked(); } } mPerInstanceDictionaryUpdateController.mLastUpdateTime = time; } finally { } finally { mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false); mProcessingLargeTask.set(false); } } } } }); }); Loading @@ -643,20 +571,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask); ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask); } } /** * For tracking whether the dictionary is out of date and the dictionary is used in a large * task. Can be shared across multiple dictionary instances that access the same filename. */ private static class DictionaryUpdateController { public volatile long mLastUpdateTime = 0; public volatile long mLastUpdateRequestTime = 0; public volatile AtomicBoolean mProcessingLargeTask = new AtomicBoolean(); public boolean isOutOfDate() { return (mLastUpdateRequestTime > mLastUpdateTime); } } // TODO: Implement BinaryDictionary.isInDictionary(). // TODO: Implement BinaryDictionary.isInDictionary(). @UsedForTesting @UsedForTesting public boolean isInUnderlyingBinaryDictionaryForTests(final String word) { public boolean isInUnderlyingBinaryDictionaryForTests(final String word) { Loading java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -116,12 +116,12 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { // devices. On older versions of the platform, the hook above will be called instead. // devices. On older versions of the platform, the hook above will be called instead. @Override @Override public void onChange(final boolean self, final Uri uri) { public void onChange(final boolean self, final Uri uri) { setRequiresReload(true); setNeedsToReload(); } } }; }; cres.registerContentObserver(Words.CONTENT_URI, true, mObserver); cres.registerContentObserver(Words.CONTENT_URI, true, mObserver); mEnabled = readIsEnabled(); mEnabled = readIsEnabled(); loadDictionary(); reloadDictionaryIfRequired(); } } @Override @Override Loading Loading
java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -89,8 +89,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { registerObserver(context); registerObserver(context); // Load the current binary dictionary from internal storage. If no binary dictionary exists, // Load the current binary dictionary from internal storage. If no binary dictionary exists, // loadDictionary will start a new thread to generate one asynchronously. // reloadDictionaryIfRequired will start a new thread to generate one asynchronously. loadDictionary(); reloadDictionaryIfRequired(); } } private synchronized void registerObserver(final Context context) { private synchronized void registerObserver(final Context context) { Loading @@ -100,7 +100,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary { new ContentObserver(null) { new ContentObserver(null) { @Override @Override public void onChange(boolean self) { public void onChange(boolean self) { setRequiresReload(true); setNeedsToReload(); } } }); }); } } Loading
java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +16 −102 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.makedict.WordProperty; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.utils.AsyncResultHolder; import com.android.inputmethod.latin.utils.AsyncResultHolder; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.CombinedFormatUtils; import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.ExecutorUtils; import com.android.inputmethod.latin.utils.FileUtils; import com.android.inputmethod.latin.utils.FileUtils; Loading @@ -38,7 +37,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.Locale; import java.util.Locale; import java.util.Map; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean; Loading Loading @@ -74,15 +72,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4; private static final int DICTIONARY_FORMAT_VERSION = FormatSpec.VERSION4; /** * A static map of update controllers, each of which records the time of accesses to a single * binary dictionary file and tracks whether the file is regenerating. The key for this map is * the dictionary name and the value is the shared dictionary time recorder associated with * that dictionary name. */ private static final ConcurrentHashMap<String, DictionaryUpdateController> sDictNameDictionaryUpdateControllerMap = CollectionUtils.newConcurrentHashMap(); /** The application context. */ /** The application context. */ protected final Context mContext; protected final Context mContext; Loading @@ -105,14 +94,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { /** Dictionary file */ /** Dictionary file */ private final File mDictFile; private final File mDictFile; // TODO: remove, once dynamic operations is serialized private final AtomicBoolean mProcessingLargeTask; /** Controls updating the shared binary dictionary file across multiple instances. */ private boolean mNeedsToReload; private final DictionaryUpdateController mDictNameDictionaryUpdateController; // TODO: remove, once dynamic operations is serialized /** Controls updating the local binary dictionary for this instance. */ private final DictionaryUpdateController mPerInstanceDictionaryUpdateController = new DictionaryUpdateController(); /* A extension for a binary dictionary file. */ /* A extension for a binary dictionary file. */ protected static final String DICT_FILE_EXTENSION = ".dict"; protected static final String DICT_FILE_EXTENSION = ".dict"; Loading Loading @@ -145,21 +129,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return mBinaryDictionary.isValidDictionary(); return mBinaryDictionary.isValidDictionary(); } } /** * Gets the dictionary update controller for the given dictionary name. */ private static DictionaryUpdateController getDictionaryUpdateController( final String dictName) { DictionaryUpdateController recorder = sDictNameDictionaryUpdateControllerMap.get(dictName); if (recorder == null) { synchronized(sDictNameDictionaryUpdateControllerMap) { recorder = new DictionaryUpdateController(); sDictNameDictionaryUpdateControllerMap.put(dictName, recorder); } } return recorder; } /** /** * Creates a new expandable binary dictionary. * Creates a new expandable binary dictionary. * * Loading @@ -179,7 +148,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { mLocale = locale; mLocale = locale; mDictFile = getDictFile(context, dictName, dictFile); mDictFile = getDictFile(context, dictName, dictFile); mBinaryDictionary = null; mBinaryDictionary = null; mDictNameDictionaryUpdateController = getDictionaryUpdateController(dictName); mProcessingLargeTask = new AtomicBoolean(); mNeedsToReload = false; } } public static File getDictFile(final Context context, final String dictName, public static File getDictFile(final Context context, final String dictName, Loading Loading @@ -286,7 +256,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { try { try { mBinaryDictionary.flushWithGC(); mBinaryDictionary.flushWithGC(); } finally { } finally { mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false); mProcessingLargeTask.set(false); } } } } }); }); Loading Loading @@ -388,7 +358,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { callback.onFinished(); callback.onFinished(); } } if (locked) { if (locked) { mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false); mProcessingLargeTask.set(false); } } } } } } Loading Loading @@ -461,25 +431,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return mBinaryDictionary.isValidBigram(word1, word2); return mBinaryDictionary.isValidBigram(word1, word2); } } /** * Load the current binary dictionary from internal storage in a background thread. If no binary * dictionary exists, this method will generate one. */ protected void loadDictionary() { mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = System.currentTimeMillis(); reloadDictionaryIfRequired(); } /** /** * Loads the current binary dictionary from internal storage. Assumes the dictionary file * Loads the current binary dictionary from internal storage. Assumes the dictionary file * exists. * exists. */ */ private void loadBinaryDictionaryLocked() { private void loadBinaryDictionaryLocked() { if (DEBUG) { Log.d(TAG, "Loading binary dictionary: " + mDictName + " request=" + mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update=" + mDictNameDictionaryUpdateController.mLastUpdateTime); } if (DBG_STRESS_TEST) { if (DBG_STRESS_TEST) { // Test if this class does not cause problems when it takes long time to load binary // Test if this class does not cause problems when it takes long time to load binary // dictionary. // dictionary. Loading @@ -505,11 +461,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * Create a new binary dictionary and load initial contents. * Create a new binary dictionary and load initial contents. */ */ private void createNewDictionaryLocked() { private void createNewDictionaryLocked() { if (DEBUG) { Log.d(TAG, "Generating binary dictionary: " + mDictName + " request=" + mDictNameDictionaryUpdateController.mLastUpdateRequestTime + " update=" + mDictNameDictionaryUpdateController.mLastUpdateTime); } removeBinaryDictionaryLocked(); removeBinaryDictionaryLocked(); createOnMemoryBinaryDictionaryLocked(); createOnMemoryBinaryDictionaryLocked(); loadInitialContentsLocked(); loadInitialContentsLocked(); Loading @@ -529,20 +480,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } } /** /** * Marks that the dictionary is out of date and requires a reload. * Marks that the dictionary needs to be reloaded. * * * @param requiresRebuild Indicates that the source dictionary content has changed and a rebuild * of the binary file is required. If not true, the next reload process will only read * the current binary dictionary from file. */ */ protected void setRequiresReload(final boolean requiresRebuild) { protected void setNeedsToReload() { final long time = System.currentTimeMillis(); mNeedsToReload = true; mPerInstanceDictionaryUpdateController.mLastUpdateRequestTime = time; mDictNameDictionaryUpdateController.mLastUpdateRequestTime = time; if (DEBUG) { Log.d(TAG, "Reload request: " + mDictName + ": request=" + time + " update=" + mDictNameDictionaryUpdateController.mLastUpdateTime); } } } /** /** Loading @@ -559,18 +501,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { * Returns whether a dictionary reload is required. * Returns whether a dictionary reload is required. */ */ private boolean isReloadRequired() { private boolean isReloadRequired() { return mBinaryDictionary == null || mPerInstanceDictionaryUpdateController.isOutOfDate(); return mBinaryDictionary == null || mNeedsToReload; } } private boolean processingLargeTask() { private boolean processingLargeTask() { return mDictNameDictionaryUpdateController.mProcessingLargeTask.get(); return mProcessingLargeTask.get(); } } // Returns whether the dictionary is being used for a large task. If true, we should not use // Returns whether the dictionary is being used for a large task. If true, we should not use // this dictionary for latency sensitive operations. // this dictionary for latency sensitive operations. private boolean setProcessingLargeTaskIfNot() { private boolean setProcessingLargeTaskIfNot() { return mDictNameDictionaryUpdateController.mProcessingLargeTask.compareAndSet( return mProcessingLargeTask.compareAndSet(false /* expect */ , true /* update */); false /* expect */ , true /* update */); } } /** /** Loading @@ -584,28 +525,17 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { @Override @Override public void run() { public void run() { try { try { final long time = System.currentTimeMillis(); if (!dictionaryFileExists() || haveContentsChanged()) { final boolean openedDictIsOutOfDate = mDictNameDictionaryUpdateController.isOutOfDate(); if (!dictionaryFileExists() || (openedDictIsOutOfDate && haveContentsChanged())) { // If the shared dictionary file does not exist or is out of date and // If the shared dictionary file does not exist or is out of date and // contents have been updated, the first instance that acquires the lock // contents have been updated, the first instance that acquires the lock // will generate a new one // will generate a new one mDictNameDictionaryUpdateController.mLastUpdateTime = time; createNewDictionaryLocked(); createNewDictionaryLocked(); } else if (openedDictIsOutOfDate) { } else if (mBinaryDictionary == null) { // If not, the reload request was unnecessary so revert // LastUpdateRequestTime to LastUpdateTime. mDictNameDictionaryUpdateController.mLastUpdateRequestTime = mDictNameDictionaryUpdateController.mLastUpdateTime; } else if (mBinaryDictionary == null || mPerInstanceDictionaryUpdateController.mLastUpdateTime < mDictNameDictionaryUpdateController.mLastUpdateTime) { // Otherwise, if the local dictionary is older than the shared dictionary, // Otherwise, if the local dictionary is older than the shared dictionary, // load the shared dictionary. // load the shared dictionary. loadBinaryDictionaryLocked(); loadBinaryDictionaryLocked(); } } mNeedsToReload = false; if (mBinaryDictionary != null && !(isValidDictionaryLocked() if (mBinaryDictionary != null && !(isValidDictionaryLocked() // TODO: remove the check below // TODO: remove the check below && matchesExpectedBinaryDictFormatVersionForThisType( && matchesExpectedBinaryDictFormatVersionForThisType( Loading @@ -613,12 +543,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { // Binary dictionary or its format version is not valid. Regenerate // Binary dictionary or its format version is not valid. Regenerate // the dictionary file. writeBinaryDictionary will remove the // the dictionary file. writeBinaryDictionary will remove the // existing files if appropriate. // existing files if appropriate. mDictNameDictionaryUpdateController.mLastUpdateTime = time; createNewDictionaryLocked(); createNewDictionaryLocked(); } } mPerInstanceDictionaryUpdateController.mLastUpdateTime = time; } finally { } finally { mDictNameDictionaryUpdateController.mProcessingLargeTask.set(false); mProcessingLargeTask.set(false); } } } } }); }); Loading @@ -643,20 +571,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask); ExecutorUtils.getExecutor(mDictName).replaceAndExecute(oldTask, newTask); } } /** * For tracking whether the dictionary is out of date and the dictionary is used in a large * task. Can be shared across multiple dictionary instances that access the same filename. */ private static class DictionaryUpdateController { public volatile long mLastUpdateTime = 0; public volatile long mLastUpdateRequestTime = 0; public volatile AtomicBoolean mProcessingLargeTask = new AtomicBoolean(); public boolean isOutOfDate() { return (mLastUpdateRequestTime > mLastUpdateTime); } } // TODO: Implement BinaryDictionary.isInDictionary(). // TODO: Implement BinaryDictionary.isInDictionary(). @UsedForTesting @UsedForTesting public boolean isInUnderlyingBinaryDictionaryForTests(final String word) { public boolean isInUnderlyingBinaryDictionaryForTests(final String word) { Loading
java/src/com/android/inputmethod/latin/UserBinaryDictionary.java +2 −2 Original line number Original line Diff line number Diff line Loading @@ -116,12 +116,12 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary { // devices. On older versions of the platform, the hook above will be called instead. // devices. On older versions of the platform, the hook above will be called instead. @Override @Override public void onChange(final boolean self, final Uri uri) { public void onChange(final boolean self, final Uri uri) { setRequiresReload(true); setNeedsToReload(); } } }; }; cres.registerContentObserver(Words.CONTENT_URI, true, mObserver); cres.registerContentObserver(Words.CONTENT_URI, true, mObserver); mEnabled = readIsEnabled(); mEnabled = readIsEnabled(); loadDictionary(); reloadDictionaryIfRequired(); } } @Override @Override Loading