aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsContentObserver.java4
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java2
-rw-r--r--java/src/com/android/inputmethod/latin/NgramContext.java7
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java112
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();
+ }
}
}
}