Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eaa710d4 authored by Dan Zivkovic's avatar Dan Zivkovic
Browse files

Separate executor for the Spelling decoder.

Bug 19710676.

Change-Id: I6e66eddd507c11e424105869833fe6841b90275d
parent 26fb83c4
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -56,8 +56,8 @@ public class ContactsContentObserver implements Runnable {
        mContentObserver = new ContentObserver(null /* handler */) {
        mContentObserver = new ContentObserver(null /* handler */) {
            @Override
            @Override
            public void onChange(boolean self) {
            public void onChange(boolean self) {
                // TODO(zivkovic): Schedule a separate task to reset the decoder.
                ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD)
                ExecutorUtils.getBackgroundExecutor().execute(ContactsContentObserver.this);
                        .execute(ContactsContentObserver.this);
            }
            }
        };
        };
        final ContentResolver contentResolver = mContext.getContentResolver();
        final ContentResolver contentResolver = mContext.getContentResolver();
+1 −1
Original line number Original line Diff line number Diff line
@@ -338,7 +338,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
            final Locale locale, final DictionaryInitializationListener listener) {
            final Locale locale, final DictionaryInitializationListener listener) {
        final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
        final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
        mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
        mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
        ExecutorUtils.getBackgroundExecutor().execute(new Runnable() {
        ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(new Runnable() {
            @Override
            @Override
            public void run() {
            public void run() {
                doReloadUninitializedMainDictionaries(
                doReloadUninitializedMainDictionaries(
+1 −1
Original line number Original line Diff line number Diff line
@@ -168,7 +168,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
    }
    }


    private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) {
    private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) {
        ExecutorUtils.getBackgroundExecutor().execute(new Runnable() {
        ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(new Runnable() {
            @Override
            @Override
            public void run() {
            public void run() {
                lock.lock();
                lock.lock();
+3 −3
Original line number Original line Diff line number Diff line
@@ -143,8 +143,8 @@ public class UserDictionaryLookup implements Closeable {
            }
            }


            // Schedule a new reload after RELOAD_DELAY_MS.
            // Schedule a new reload after RELOAD_DELAY_MS.
            mReloadFuture = ExecutorUtils.getBackgroundExecutor().schedule(
            mReloadFuture = ExecutorUtils.getBackgroundExecutor(ExecutorUtils.SPELLING)
                    mLoader, RELOAD_DELAY_MS, TimeUnit.MILLISECONDS);
                    .schedule(mLoader, RELOAD_DELAY_MS, TimeUnit.MILLISECONDS);
        }
        }
    }
    }
    private final ContentObserver mObserver = new UserDictionaryContentObserver();
    private final ContentObserver mObserver = new UserDictionaryContentObserver();
@@ -186,7 +186,7 @@ public class UserDictionaryLookup implements Closeable {
        // Schedule the initial load to run immediately.  It's possible that the first call to
        // 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
        // isValidWord occurs before the dictionary has actually loaded, so it should not
        // assume that the dictionary has been loaded.
        // assume that the dictionary has been loaded.
        ExecutorUtils.getBackgroundExecutor().execute(mLoader);
        ExecutorUtils.getBackgroundExecutor(ExecutorUtils.SPELLING).execute(mLoader);


        // Register the observer to be notified on changes to the UserDictionary and all individual
        // Register the observer to be notified on changes to the UserDictionary and all individual
        // items.
        // items.
+45 −12
Original line number Original line Diff line number Diff line
@@ -33,17 +33,30 @@ public class ExecutorUtils {


    private static final String TAG = "ExecutorUtils";
    private static final String TAG = "ExecutorUtils";


    private static ScheduledExecutorService sExecutorService =
    public static final String KEYBOARD = "Keyboard";
            Executors.newSingleThreadScheduledExecutor(new ExecutorFactory());
    public static final String SPELLING = "Spelling";

    private static ScheduledExecutorService sKeyboardExecutorService = newExecutorService(KEYBOARD);
    private static ScheduledExecutorService sSpellingExecutorService = newExecutorService(SPELLING);

    private static ScheduledExecutorService newExecutorService(final String name) {
        return Executors.newSingleThreadScheduledExecutor(new ExecutorFactory(name));
    }


    private static class ExecutorFactory implements ThreadFactory {
    private static class ExecutorFactory implements ThreadFactory {
        private final String mName;

        private ExecutorFactory(final String name) {
            mName = name;
        }

        @Override
        @Override
        public Thread newThread(final Runnable runnable) {
        public Thread newThread(final Runnable runnable) {
            Thread thread = new Thread(runnable, TAG);
            Thread thread = new Thread(runnable, TAG);
            thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
            thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
                @Override
                @Override
                public void uncaughtException(Thread thread, Throwable ex) {
                public void uncaughtException(Thread thread, Throwable ex) {
                    Log.w(TAG + "-" + runnable.getClass().getSimpleName(), ex);
                    Log.w(mName + "-" + runnable.getClass().getSimpleName(), ex);
                }
                }
            });
            });
            return thread;
            return thread;
@@ -64,24 +77,44 @@ public class ExecutorUtils {
    //
    //


    /**
    /**
     * @param name Executor's name.
     * @return scheduled executor service used to run background tasks
     * @return scheduled executor service used to run background tasks
     */
     */
    public static ScheduledExecutorService getBackgroundExecutor() {
    public static ScheduledExecutorService getBackgroundExecutor(final String name) {
        if (sExecutorServiceForTests != null) {
        if (sExecutorServiceForTests != null) {
            return sExecutorServiceForTests;
            return sExecutorServiceForTests;
        }
        }
        return sExecutorService;
        switch (name) {
            case KEYBOARD:
                return sKeyboardExecutorService;
            case SPELLING:
                return sSpellingExecutorService;
            default:
                throw new IllegalArgumentException("Invalid executor: " + name);
        }
    }
    }


    public static void killTasks() {
    public static void killTasks(final String name) {
        getBackgroundExecutor().shutdownNow();
        final ScheduledExecutorService executorService = getBackgroundExecutor(name);
        executorService.shutdownNow();
        try {
        try {
            getBackgroundExecutor().awaitTermination(5, TimeUnit.SECONDS);
            executorService.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
        } catch (InterruptedException e) {
            Log.wtf(TAG, "Failed to shut down background task.");
            Log.wtf(TAG, "Failed to shut down: " + name);
            throw new IllegalStateException("Failed to shut down background task.");
        }
        } finally {
        if (executorService == sExecutorServiceForTests) {
            sExecutorService = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory());
            // Don't do anything to the test service.
            return;
        }
        switch (name) {
            case KEYBOARD:
                sKeyboardExecutorService = newExecutorService(KEYBOARD);
                break;
            case SPELLING:
                sSpellingExecutorService = newExecutorService(SPELLING);
                break;
            default:
                throw new IllegalArgumentException("Invalid executor: " + name);
        }
        }
    }
    }


Loading