diff options
Diffstat (limited to 'java/src/com')
6 files changed, 56 insertions, 75 deletions
diff --git a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java index e45681bd7..4a8d1133b 100644 --- a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java +++ b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java @@ -56,8 +56,8 @@ public class ContactsContentObserver implements Runnable { mContentObserver = new ContentObserver(null /* handler */) { @Override public void onChange(boolean self) { - ExecutorUtils.getExecutorForDynamicLanguageModelUpdate() - .execute(ContactsContentObserver.this); + // TODO(zivkovic): Schedule a separate task to reset the decoder. + ExecutorUtils.getBackgroundExecutor().execute(ContactsContentObserver.this); } }; final ContentResolver contentResolver = mContext.getContentResolver(); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java index 7ad2a9f7d..6080900a1 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java @@ -444,7 +444,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { final Locale[] locales, final DictionaryInitializationListener listener) { final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1); mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary; - ExecutorUtils.getExecutorForStaticLanguageModelUpdate().execute(new Runnable() { + ExecutorUtils.getBackgroundExecutor().execute(new Runnable() { @Override public void run() { doReloadUninitializedMainDictionaries( diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index b0fb91bec..138a2ea5c 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -168,7 +168,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) { - ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().execute(new Runnable() { + ExecutorUtils.getBackgroundExecutor().execute(new Runnable() { @Override public void run() { lock.lock(); diff --git a/java/src/com/android/inputmethod/latin/NgramContext.java b/java/src/com/android/inputmethod/latin/NgramContext.java index c9351586e..aeeff6126 100644 --- a/java/src/com/android/inputmethod/latin/NgramContext.java +++ b/java/src/com/android/inputmethod/latin/NgramContext.java @@ -142,8 +142,7 @@ public class NgramContext { } } } - return terms.size() == 0 ? BEGINNING_OF_SENTENCE_TAG - : TextUtils.join(CONTEXT_SEPARATOR, terms); + return TextUtils.join(CONTEXT_SEPARATOR, terms); } /** @@ -166,9 +165,7 @@ public class NgramContext { } } } - final String[] contextStringArray = prevTermList.size() == 0 ? - new String[] { BEGINNING_OF_SENTENCE_TAG } - : prevTermList.toArray(new String[prevTermList.size()]); + final String[] contextStringArray = prevTermList.toArray(new String[prevTermList.size()]); return contextStringArray; } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java b/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java index 856f16a53..6ab741ca1 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java @@ -143,7 +143,7 @@ public class UserDictionaryLookup implements Closeable { } // Schedule a new reload after RELOAD_DELAY_MS. - mReloadFuture = ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().schedule( + mReloadFuture = ExecutorUtils.getBackgroundExecutor().schedule( mLoader, RELOAD_DELAY_MS, TimeUnit.MILLISECONDS); } } @@ -186,7 +186,7 @@ public class UserDictionaryLookup implements Closeable { // Schedule the initial load to run immediately. It's possible that the first call to // isValidWord occurs before the dictionary has actually loaded, so it should not // assume that the dictionary has been loaded. - ExecutorUtils.getExecutorForDynamicLanguageModelUpdate().execute(mLoader); + ExecutorUtils.getBackgroundExecutor().execute(mLoader); // Register the observer to be notified on changes to the UserDictionary and all individual // items. diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java index c533a6273..91714686f 100644 --- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java @@ -21,21 +21,34 @@ import android.util.Log; import com.android.inputmethod.annotations.UsedForTesting; import java.lang.Thread.UncaughtExceptionHandler; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; /** * Utilities to manage executors. */ public class ExecutorUtils { - private static final String STATIC_LANGUAGE_MODEL_UPDATE = "StaticLanguageModelUpdate"; - private static final String DYNAMIC_LANGUAGE_MODEL_UPDATE = "DynamicLanguageModelUpdate"; + private static final String TAG = "ExecutorUtils"; - private static final ConcurrentHashMap<String, ScheduledExecutorService> sExecutorMap = - new ConcurrentHashMap<>(); + private static ScheduledExecutorService sExecutorService = + Executors.newSingleThreadScheduledExecutor(new ExecutorFactory()); + + private static class ExecutorFactory implements ThreadFactory { + @Override + public Thread newThread(final Runnable runnable) { + Thread thread = new Thread(runnable, TAG); + thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread thread, Throwable ex) { + Log.w(TAG + "-" + runnable.getClass().getSimpleName(), ex); + } + }); + return thread; + } + } @UsedForTesting private static ScheduledExecutorService sExecutorServiceForTests; @@ -46,83 +59,54 @@ public class ExecutorUtils { sExecutorServiceForTests = executorServiceForTests; } - /** - * @return scheduled executor service used to update static language models - */ - public static ScheduledExecutorService getExecutorForStaticLanguageModelUpdate() { - return getExecutor(STATIC_LANGUAGE_MODEL_UPDATE); - } - - /** - * @return scheduled executor service used to update dynamic language models - */ - public static ScheduledExecutorService getExecutorForDynamicLanguageModelUpdate() { - return getExecutor(DYNAMIC_LANGUAGE_MODEL_UPDATE); - } + // + // Public methods used to schedule a runnable for execution. + // /** - * Gets the executor for the given id. + * @return scheduled executor service used to run background tasks */ - private static ScheduledExecutorService getExecutor(final String id) { + public static ScheduledExecutorService getBackgroundExecutor() { if (sExecutorServiceForTests != null) { return sExecutorServiceForTests; } - ScheduledExecutorService executor = sExecutorMap.get(id); - if (executor == null) { - synchronized (sExecutorMap) { - executor = sExecutorMap.get(id); - if (executor == null) { - executor = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory(id)); - sExecutorMap.put(id, executor); - } - } - } - return executor; + return sExecutorService; } - /** - * Shutdowns all executors and removes all executors from the executor map for testing. - */ - @UsedForTesting - public static void shutdownAllExecutors() { - synchronized (sExecutorMap) { - for (final ScheduledExecutorService executor : sExecutorMap.values()) { - executor.execute(new ExecutorShutdown(executor)); - } - sExecutorMap.clear(); + public static void killTasks() { + getBackgroundExecutor().shutdownNow(); + try { + getBackgroundExecutor().awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Log.wtf(TAG, "Failed to shut down background task."); + throw new IllegalStateException("Failed to shut down background task."); + } finally { + sExecutorService = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory()); } } - private static class ExecutorFactory implements ThreadFactory { - private final String mThreadName; - - public ExecutorFactory(final String threadName) { - mThreadName = threadName; - } - - @Override - public Thread newThread(final Runnable runnable) { - Thread thread = new Thread(runnable, mThreadName); - thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread thread, Throwable ex) { - Log.w(mThreadName + "-" + runnable.getClass().getSimpleName(), ex); - } - }); - return thread; - } + public static Runnable chain(final Runnable... runnables) { + return new RunnableChain(runnables); } - private static class ExecutorShutdown implements Runnable { - private final ScheduledExecutorService mExecutor; + private static class RunnableChain implements Runnable { + private final Runnable[] mRunnables; - public ExecutorShutdown(final ScheduledExecutorService executor) { - mExecutor = executor; + private RunnableChain(final Runnable... runnables) { + if (runnables == null || runnables.length == 0) { + throw new IllegalArgumentException("Attempting to construct an empty chain"); + } + mRunnables = runnables; } @Override public void run() { - mExecutor.shutdown(); + for (Runnable runnable : mRunnables) { + if (Thread.interrupted()) { + return; + } + runnable.run(); + } } } } |