diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index cc203f7..b9be118 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -723,7 +723,7 @@
         unregisterReceiver(mBatteryInfoReceiver);
         unregisterReceiver(mUserAddRemoveReceiver);
         if (mDynamicIndexableContentMonitor != null) {
-            mDynamicIndexableContentMonitor.unregister();
+            mDynamicIndexableContentMonitor.unregister(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
         }
     }
 
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index 44bf435..e122244 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -222,6 +222,7 @@
             InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(
                     Context.INPUT_METHOD_SERVICE);
 
+            // TODO: Move to VirtualKeyboardFragment and AvailableVirtualKeyboardFragment.
             // All other IMEs.
             List<InputMethodInfo> inputMethods = immValues.getInputMethodList();
             final int inputMethodCount = (inputMethods == null ? 0 : inputMethods.size());
@@ -245,6 +246,7 @@
                 indexables.add(indexable);
             }
 
+            // TODO: Move to PhysicalKeyboardFragment.
             // Hard keyboards
             InputManager inputManager = (InputManager) context.getSystemService(
                     Context.INPUT_SERVICE);
diff --git a/src/com/android/settings/search/DynamicIndexableContentMonitor.java b/src/com/android/settings/search/DynamicIndexableContentMonitor.java
index a24ec50..34cdeba 100644
--- a/src/com/android/settings/search/DynamicIndexableContentMonitor.java
+++ b/src/com/android/settings/search/DynamicIndexableContentMonitor.java
@@ -20,6 +20,7 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.Activity;
 import android.app.LoaderManager;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.Loader;
@@ -30,17 +31,17 @@
 import android.hardware.input.InputManager;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.print.PrintManager;
 import android.print.PrintServicesLoader;
 import android.printservice.PrintServiceInfo;
 import android.provider.UserDictionary;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.InputMethod;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 
@@ -52,227 +53,100 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public final class DynamicIndexableContentMonitor extends PackageMonitor implements
-        InputManager.InputDeviceListener,
+public final class DynamicIndexableContentMonitor implements
         LoaderManager.LoaderCallbacks<List<PrintServiceInfo>> {
-    private static final String TAG = "DynamicIndexableContentMonitor";
+    // Shorten the class name because log TAG can be at most 23 chars.
+    private static final String TAG = "DynamicContentMonitor";
 
-    private static final long DELAY_PROCESS_PACKAGE_CHANGE = 2000;
+    @VisibleForTesting
+    static final long DELAY_PROCESS_PACKAGE_CHANGE = 2000;
 
-    private static final int MSG_PACKAGE_AVAILABLE = 1;
-    private static final int MSG_PACKAGE_UNAVAILABLE = 2;
-
-    private final List<String> mAccessibilityServices = new ArrayList<String>();
-    private final List<String> mImeServices = new ArrayList<String>();
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_PACKAGE_AVAILABLE: {
-                    String packageName = (String) msg.obj;
-                    handlePackageAvailable(packageName);
-                } break;
-
-                case MSG_PACKAGE_UNAVAILABLE: {
-                    String packageName = (String) msg.obj;
-                    handlePackageUnavailable(packageName);
-                } break;
-            }
-        }
-    };
-
-    private final ContentObserver mUserDictionaryContentObserver =
-            new UserDictionaryContentObserver(mHandler);
-
+    // Null if not initialized.
+    @Nullable private Index mIndex;
     private Context mContext;
-    private boolean mHasFeatureIme;
-    private boolean mRegistered;
+    private boolean mHasFeaturePrinting;
 
-    private static Intent getAccessibilityServiceIntent(String packageName) {
+    @VisibleForTesting
+    static Intent getAccessibilityServiceIntent(String packageName) {
         final Intent intent = new Intent(AccessibilityService.SERVICE_INTERFACE);
         intent.setPackage(packageName);
         return intent;
     }
 
-    private static Intent getIMEServiceIntent(String packageName) {
-        final Intent intent = new Intent("android.view.InputMethod");
+    @VisibleForTesting
+    static Intent getIMEServiceIntent(String packageName) {
+        final Intent intent = new Intent(InputMethod.SERVICE_INTERFACE);
         intent.setPackage(packageName);
         return intent;
     }
 
+    @VisibleForTesting
+    static void resetForTesting() {
+        InputDevicesMonitor.getInstance().resetForTesting();
+        PackageChangeMonitor.getInstance().resetForTesting();
+    }
+
+    /**
+     * This instance holds a set of content monitor singleton objects.
+     *
+     * This object is created every time a sub-settings that extends {@code SettingsActivity}
+     * is created.
+     */
+    public DynamicIndexableContentMonitor() {}
+
+    /**
+     * Creates and initializes a set of content monitor singleton objects if not yet exist.
+     * Also starts loading the list of print services.
+     * <code>mIndex</code> has non-null value after successfully initialized.
+     *
+     * @param activity used to get {@link LoaderManager}.
+     * @param loaderId id for loading print services.
+     */
     public void register(Activity activity, int loaderId) {
-        mContext = activity;
+        final boolean isUserUnlocked = activity
+                .getSystemService(UserManager.class)
+                .isUserUnlocked();
+        register(activity, loaderId, Index.getInstance(activity), isUserUnlocked);
+    }
 
-        if (!mContext.getSystemService(UserManager.class).isUserUnlocked()) {
+    /**
+     * For testing to inject {@link Index} object. Also because currently Robolectric doesn't
+     * support API 24, we can not test code that calls {@link UserManager#isUserUnlocked()}.
+     */
+    @VisibleForTesting
+    void register(Activity activity, int loaderId, Index index, boolean isUserUnlocked) {
+        if (!isUserUnlocked) {
             Log.w(TAG, "Skipping content monitoring because user is locked");
-            mRegistered = false;
             return;
-        } else {
-            mRegistered = true;
         }
+        mContext = activity;
+        mIndex = index;
 
-        boolean hasFeaturePrinting = mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_PRINTING);
-        mHasFeatureIme = mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_INPUT_METHODS);
-
-        // Cache accessibility service packages to know when they go away.
-        AccessibilityManager accessibilityManager = (AccessibilityManager)
-                mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
-        List<AccessibilityServiceInfo> accessibilityServices = accessibilityManager
-                .getInstalledAccessibilityServiceList();
-        final int accessibilityServiceCount = accessibilityServices.size();
-        for (int i = 0; i < accessibilityServiceCount; i++) {
-            AccessibilityServiceInfo accessibilityService = accessibilityServices.get(i);
-            ResolveInfo resolveInfo = accessibilityService.getResolveInfo();
-            if (resolveInfo == null || resolveInfo.serviceInfo == null) {
-                continue;
-            }
-            mAccessibilityServices.add(resolveInfo.serviceInfo.packageName);
-        }
-
-        if (hasFeaturePrinting) {
-            activity.getLoaderManager().initLoader(loaderId, null, this);
-        }
-
-        // Cache IME service packages to know when they go away.
-        if (mHasFeatureIme) {
-            InputMethodManager imeManager = (InputMethodManager)
-                    mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
-            List<InputMethodInfo> inputMethods = imeManager.getInputMethodList();
-            final int inputMethodCount = inputMethods.size();
-            for (int i = 0; i < inputMethodCount; i++) {
-                InputMethodInfo inputMethod = inputMethods.get(i);
-                ServiceInfo serviceInfo = inputMethod.getServiceInfo();
-                if (serviceInfo == null) continue;
-                mImeServices.add(serviceInfo.packageName);
-            }
-
-            // Watch for related content URIs.
-            mContext.getContentResolver().registerContentObserver(
-                    UserDictionary.Words.CONTENT_URI, true, mUserDictionaryContentObserver);
+        mHasFeaturePrinting = mContext.getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_PRINTING);
+        if (mHasFeaturePrinting) {
+            activity.getLoaderManager().initLoader(loaderId, null /* args */, this /* callbacks */);
         }
 
         // Watch for input device changes.
-        InputManager inputManager = (InputManager) activity.getSystemService(
-                Context.INPUT_SERVICE);
-        inputManager.registerInputDeviceListener(this, mHandler);
+        InputDevicesMonitor.getInstance().initialize(mContext, mIndex);
 
         // Start tracking packages.
-        register(activity, Looper.getMainLooper(), UserHandle.CURRENT, false);
+        PackageChangeMonitor.getInstance().initialize(mContext, mIndex);
     }
 
-    @Override
-    public void unregister() {
-        if (!mRegistered) return;
+    /**
+     * Aborts loading the list of print services.
+     * Note that a set of content monitor singletons keep alive while Settings app is running.
+     *
+     * @param activity user to get {@link LoaderManager}.
+     * @param loaderId id for loading print services.
+     */
+    public void unregister(Activity activity, int loaderId) {
+        if (mIndex == null) return;
 
-        super.unregister();
-
-        InputManager inputManager = (InputManager) mContext.getSystemService(
-                Context.INPUT_SERVICE);
-        inputManager.unregisterInputDeviceListener(this);
-
-        if (mHasFeatureIme) {
-            mContext.getContentResolver().unregisterContentObserver(
-                    mUserDictionaryContentObserver);
-        }
-
-        mAccessibilityServices.clear();
-        mImeServices.clear();
-    }
-
-    // Covers installed, appeared external storage with the package, upgraded.
-    @Override
-    public void onPackageAppeared(String packageName, int uid) {
-        postMessage(MSG_PACKAGE_AVAILABLE, packageName);
-    }
-
-    // Covers uninstalled, removed external storage with the package.
-    @Override
-    public void onPackageDisappeared(String packageName, int uid) {
-        postMessage(MSG_PACKAGE_UNAVAILABLE, packageName);
-    }
-
-    // Covers enabled, disabled.
-    @Override
-    public void onPackageModified(String packageName) {
-        super.onPackageModified(packageName);
-        try {
-            final int state = mContext.getPackageManager().getApplicationEnabledSetting(
-                    packageName);
-            if (state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
-                    || state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
-                postMessage(MSG_PACKAGE_AVAILABLE, packageName);
-            } else {
-                postMessage(MSG_PACKAGE_UNAVAILABLE, packageName);
-            }
-        } catch (IllegalArgumentException e) {
-            Log.e(TAG, "Package does not exist: " + packageName, e);
-        }
-    }
-
-    @Override
-    public void onInputDeviceAdded(int deviceId) {
-        Index.getInstance(mContext).updateFromClassNameResource(
-                InputMethodAndLanguageSettings.class.getName(), false, true);
-    }
-
-    @Override
-    public void onInputDeviceRemoved(int deviceId) {
-        onInputDeviceChanged(deviceId);
-    }
-
-    @Override
-    public void onInputDeviceChanged(int deviceId) {
-        Index.getInstance(mContext).updateFromClassNameResource(
-                InputMethodAndLanguageSettings.class.getName(), true, true);
-    }
-
-    private void postMessage(int what, String packageName) {
-        Message message = mHandler.obtainMessage(what, packageName);
-        mHandler.sendMessageDelayed(message, DELAY_PROCESS_PACKAGE_CHANGE);
-    }
-
-    private void handlePackageAvailable(String packageName) {
-        if (!mAccessibilityServices.contains(packageName)) {
-            final Intent intent = getAccessibilityServiceIntent(packageName);
-            List<?> services = mContext.getPackageManager().queryIntentServices(intent, 0);
-            if (services != null && !services.isEmpty()) {
-                mAccessibilityServices.add(packageName);
-                Index.getInstance(mContext).updateFromClassNameResource(
-                        AccessibilitySettings.class.getName(), false, true);
-            }
-        }
-
-        if (mHasFeatureIme) {
-            if (!mImeServices.contains(packageName)) {
-                Intent intent = getIMEServiceIntent(packageName);
-                List<?> services = mContext.getPackageManager().queryIntentServices(intent, 0);
-                if (services != null && !services.isEmpty()) {
-                    mImeServices.add(packageName);
-                    Index.getInstance(mContext).updateFromClassNameResource(
-                            InputMethodAndLanguageSettings.class.getName(), false, true);
-                }
-            }
-        }
-    }
-
-    private void handlePackageUnavailable(String packageName) {
-        final int accessibilityIndex = mAccessibilityServices.indexOf(packageName);
-        if (accessibilityIndex >= 0) {
-            mAccessibilityServices.remove(accessibilityIndex);
-            Index.getInstance(mContext).updateFromClassNameResource(
-                    AccessibilitySettings.class.getName(), true, true);
-        }
-
-        if (mHasFeatureIme) {
-            final int imeIndex = mImeServices.indexOf(packageName);
-            if (imeIndex >= 0) {
-                mImeServices.remove(imeIndex);
-                Index.getInstance(mContext).updateFromClassNameResource(
-                        InputMethodAndLanguageSettings.class.getName(), true, true);
-            }
+        if (mHasFeaturePrinting) {
+            activity.getLoaderManager().destroyLoader(loaderId);
         }
     }
 
@@ -286,8 +160,8 @@
     @Override
     public void onLoadFinished(Loader<List<PrintServiceInfo>> loader,
             List<PrintServiceInfo> services) {
-        Index.getInstance(mContext).updateFromClassNameResource(
-                PrintSettingsFragment.class.getName(), false, true);
+        mIndex.updateFromClassNameResource(PrintSettingsFragment.class.getName(),
+                false /* rebuild */, true /* includeInSearchResult */);
     }
 
     @Override
@@ -295,18 +169,304 @@
         // nothing to do
     }
 
-    private final class UserDictionaryContentObserver extends ContentObserver {
+    // A singleton that monitors input devices changes and updates indexes of physical keyboards.
+    private static class InputDevicesMonitor implements InputManager.InputDeviceListener {
 
-        public UserDictionaryContentObserver(Handler handler) {
-            super(handler);
+        // Null if not initialized.
+        @Nullable private Index mIndex;
+        private InputManager mInputManager;
+
+        private InputDevicesMonitor() {}
+
+        private static class SingletonHolder {
+            private static final InputDevicesMonitor INSTANCE = new InputDevicesMonitor();
+        }
+
+        static InputDevicesMonitor getInstance() {
+            return SingletonHolder.INSTANCE;
+        }
+
+        @VisibleForTesting
+        synchronized void resetForTesting() {
+            if (mIndex != null) {
+                mInputManager.unregisterInputDeviceListener(this /* listener */);
+            }
+            mIndex = null;
+        }
+
+        synchronized void initialize(Context context, Index index) {
+            if (mIndex != null) return;
+            mIndex = index;
+            mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
+            buildIndex(true /* rebuild */);
+
+            // Watch for input device changes.
+            mInputManager.registerInputDeviceListener(this /* listener */, null /* handler */);
+        }
+
+        private void buildIndex(boolean rebuild) {
+            // TODO: Fix landing page to PhysicalKeyboardFragment.
+            mIndex.updateFromClassNameResource(InputMethodAndLanguageSettings.class.getName(),
+                    rebuild, true /* includeInSearchResult */);
+        }
+
+        @Override
+        public void onInputDeviceAdded(int deviceId) {
+            buildIndex(false /* rebuild */);
+        }
+
+        @Override
+        public void onInputDeviceRemoved(int deviceId) {
+            buildIndex(true /* rebuild */);
+        }
+
+        @Override
+        public void onInputDeviceChanged(int deviceId) {
+            buildIndex(true /* rebuild */);
+        }
+    }
+
+    // A singleton that monitors package installing, uninstalling, enabling, and disabling.
+    // Then updates indexes of accessibility services and input methods.
+    private static class PackageChangeMonitor extends PackageMonitor {
+        private static final String TAG = PackageChangeMonitor.class.getSimpleName();
+
+        // Null if not initialized.
+        @Nullable private PackageManager mPackageManager;
+
+        private PackageChangeMonitor() {}
+
+        private static class SingletonHolder {
+            private static final PackageChangeMonitor INSTANCE = new PackageChangeMonitor();
+        }
+
+        static PackageChangeMonitor getInstance() {
+            return SingletonHolder.INSTANCE;
+        }
+
+        @VisibleForTesting
+        synchronized void resetForTesting() {
+            if (mPackageManager != null) {
+                unregister();
+            }
+            mPackageManager = null;
+            AccessibilityServicesMonitor.getInstance().resetForTesting();
+            InputMethodServicesMonitor.getInstance().resetForTesting();
+        }
+
+        synchronized void initialize(Context context, Index index) {
+            if (mPackageManager != null) return;;
+            mPackageManager = context.getPackageManager();
+
+            AccessibilityServicesMonitor.getInstance().initialize(context, index);
+            InputMethodServicesMonitor.getInstance().initialize(context, index);
+
+            // Start tracking packages. Use background thread for monitoring. Note that no need to
+            // unregister this monitor. This should be alive while Settings app is running.
+            register(context, null /* thread */, UserHandle.CURRENT, false);
+        }
+
+        // Covers installed, appeared external storage with the package, upgraded.
+        @Override
+        public void onPackageAppeared(String packageName, int uid) {
+            postPackageAvailable(packageName);
+        }
+
+        // Covers uninstalled, removed external storage with the package.
+        @Override
+        public void onPackageDisappeared(String packageName, int uid) {
+            postPackageUnavailable(packageName);
+        }
+
+        // Covers enabled, disabled.
+        @Override
+        public void onPackageModified(String packageName) {
+            try {
+                final int state = mPackageManager.getApplicationEnabledSetting(packageName);
+                if (state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+                        || state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
+                    postPackageAvailable(packageName);
+                } else {
+                    postPackageUnavailable(packageName);
+                }
+            } catch (IllegalArgumentException e) {
+                Log.e(TAG, "Package does not exist: " + packageName, e);
+            }
+        }
+
+        private void postPackageAvailable(final String packageName) {
+            getRegisteredHandler().postDelayed(() -> {
+                AccessibilityServicesMonitor.getInstance().onPackageAvailable(packageName);
+                InputMethodServicesMonitor.getInstance().onPackageAvailable(packageName);
+            }, DELAY_PROCESS_PACKAGE_CHANGE);
+        }
+
+        private void postPackageUnavailable(final String packageName) {
+            getRegisteredHandler().postDelayed(() -> {
+                AccessibilityServicesMonitor.getInstance().onPackageUnavailable(packageName);
+                InputMethodServicesMonitor.getInstance().onPackageUnavailable(packageName);
+            }, DELAY_PROCESS_PACKAGE_CHANGE);
+        }
+    }
+
+    // A singleton that holds list of available accessibility services and updates search index.
+    private static class AccessibilityServicesMonitor {
+
+        // Null if not initialized.
+        @Nullable private Index mIndex;
+        private PackageManager mPackageManager;
+        private final List<String> mAccessibilityServices = new ArrayList<>();
+
+        private AccessibilityServicesMonitor() {}
+
+        private static class SingletonHolder {
+            private static final AccessibilityServicesMonitor INSTANCE =
+                    new AccessibilityServicesMonitor();
+        }
+
+        static AccessibilityServicesMonitor getInstance() {
+            return SingletonHolder.INSTANCE;
+        }
+
+        @VisibleForTesting
+        synchronized void resetForTesting() {
+            mIndex = null;
+        }
+
+        synchronized void initialize(Context context, Index index) {
+            if (mIndex != null) return;
+            mIndex = index;
+            mPackageManager = context.getPackageManager();
+            mAccessibilityServices.clear();
+            buildIndex(true /* rebuild */);
+
+            // Cache accessibility service packages to know when they go away.
+            AccessibilityManager accessibilityManager = (AccessibilityManager) context
+                    .getSystemService(Context.ACCESSIBILITY_SERVICE);
+            for (final AccessibilityServiceInfo accessibilityService
+                    : accessibilityManager.getInstalledAccessibilityServiceList()) {
+                ResolveInfo resolveInfo = accessibilityService.getResolveInfo();
+                if (resolveInfo != null && resolveInfo.serviceInfo != null) {
+                    mAccessibilityServices.add(resolveInfo.serviceInfo.packageName);
+                }
+            }
+        }
+
+        private void buildIndex(boolean rebuild) {
+            mIndex.updateFromClassNameResource(AccessibilitySettings.class.getName(),
+                    rebuild, true /* includeInSearchResult */);
+        }
+
+        synchronized void onPackageAvailable(String packageName) {
+            if (mIndex == null) return;
+            if (mAccessibilityServices.contains(packageName)) return;
+
+            final Intent intent = getAccessibilityServiceIntent(packageName);
+            final List<ResolveInfo> services = mPackageManager
+                    .queryIntentServices(intent, 0 /* flags */);
+            if (services == null || services.isEmpty()) return;
+            mAccessibilityServices.add(packageName);
+            buildIndex(false /* rebuild */);
+        }
+
+        synchronized void onPackageUnavailable(String packageName) {
+            if (mIndex == null) return;
+            if (!mAccessibilityServices.remove(packageName)) return;
+            buildIndex(true /* rebuild */);
+        }
+    }
+
+    // A singleton that holds list of available input methods and updates search index.
+    // Also it monitors user dictionary changes and updates search index.
+    private static class InputMethodServicesMonitor extends ContentObserver {
+
+        // Null if not initialized.
+        @Nullable private Index mIndex;
+        private PackageManager mPackageManager;
+        private ContentResolver mContentResolver;
+        private final List<String> mInputMethodServices = new ArrayList<>();
+
+        private InputMethodServicesMonitor() {
+            // No need for handler because {@link #onChange(boolean,Uri)} is short and quick.
+            super(null /* handler */);
+        }
+
+        private static class SingletonHolder {
+            private static final InputMethodServicesMonitor INSTANCE =
+                    new InputMethodServicesMonitor();
+        }
+
+        static InputMethodServicesMonitor getInstance() {
+            return SingletonHolder.INSTANCE;
+        }
+
+        @VisibleForTesting
+        synchronized void resetForTesting() {
+            if (mIndex != null) {
+                mContentResolver.unregisterContentObserver(this /* observer */);
+            }
+            mIndex = null;
+        }
+
+        synchronized void initialize(Context context, Index index) {
+            final boolean hasFeatureIme = context.getPackageManager()
+                    .hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS);
+            if (!hasFeatureIme) return;
+
+            if (mIndex != null) return;
+            mIndex = index;
+            mPackageManager = context.getPackageManager();
+            mContentResolver = context.getContentResolver();
+            mInputMethodServices.clear();
+            buildIndex(InputMethodAndLanguageSettings.class, true /* rebuild */);
+
+            // Cache IME service packages to know when they go away.
+            final InputMethodManager inputMethodManager = (InputMethodManager) context
+                    .getSystemService(Context.INPUT_METHOD_SERVICE);
+            for (final InputMethodInfo inputMethod : inputMethodManager.getInputMethodList()) {
+                ServiceInfo serviceInfo = inputMethod.getServiceInfo();
+                if (serviceInfo != null) {
+                    mInputMethodServices.add(serviceInfo.packageName);
+                }
+            }
+
+            // Watch for related content URIs.
+            mContentResolver.registerContentObserver(UserDictionary.Words.CONTENT_URI,
+                    true /* notifyForDescendants */, this /* observer */);
+            // TODO: Should monitor android.provider.Settings.Secure.ENABLED_INPUT_METHODS and
+            // update index of AvailableVirtualKeyboardFragment and VirtualKeyboardFragment.
+        }
+
+        private void buildIndex(Class<?> indexClass, boolean rebuild) {
+            mIndex.updateFromClassNameResource(indexClass.getName(), rebuild,
+                    true /* includeInSearchResult */);
+        }
+
+        synchronized void onPackageAvailable(String packageName) {
+            if (mIndex == null) return;
+            if (mInputMethodServices.contains(packageName)) return;
+
+            final Intent intent = getIMEServiceIntent(packageName);
+            final List<ResolveInfo> services = mPackageManager
+                    .queryIntentServices(intent, 0 /* flags */);
+            if (services == null || services.isEmpty()) return;
+            mInputMethodServices.add(packageName);
+            // TODO: Fix landing page to VirtualKeyboardFragment.
+            buildIndex(InputMethodAndLanguageSettings.class, false /* rebuild */);
+        }
+
+        synchronized void onPackageUnavailable(String packageName) {
+            if (mIndex == null) return;
+            if (!mInputMethodServices.remove(packageName)) return;
+            // TODO: Fix landing page to AvailableVirtualKeyboardFragment.
+            buildIndex(InputMethodAndLanguageSettings.class, true /* rebuild */);
         }
 
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             if (UserDictionary.Words.CONTENT_URI.equals(uri)) {
-                Index.getInstance(mContext).updateFromClassNameResource(
-                        InputMethodAndLanguageSettings.class.getName(), true, true);
+                buildIndex(InputMethodAndLanguageSettings.class, true /* rebuild */);
             }
-        };
+        }
     }
 }
