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 */);
             }
-        };
+        }
     }
 }
diff --git a/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java b/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java
new file mode 100644
index 0000000..28fe8b0
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.search;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.only;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Activity;
+import android.app.Application;
+import android.app.LoaderManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.database.ContentObserver;
+import android.hardware.input.InputManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.print.PrintManager;
+import android.print.PrintServicesLoader;
+import android.printservice.PrintServiceInfo;
+import android.provider.UserDictionary;
+import android.view.inputmethod.InputMethodInfo;
+
+import com.android.internal.content.PackageMonitor;
+import com.android.settings.SettingsRobolectricTestRunner;
+import com.android.settings.TestConfig;
+import com.android.settings.accessibility.AccessibilitySettings;
+import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
+import com.android.settings.print.PrintSettingsFragment;
+import com.android.settings.testutils.shadow.ShadowActivityWithLoadManager;
+import com.android.settings.testutils.shadow.ShadowContextImplWithRegisterReceiver;
+import com.android.settings.testutils.shadow.ShadowInputManager;
+import com.android.settings.testutils.shadow.ShadowInputMethodManagerWithMethodList;
+import com.android.settings.testutils.shadow.ShadowPackageMonitor;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.verification.VerificationMode;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.internal.ShadowExtractor;
+import org.robolectric.res.builder.RobolectricPackageManager;
+import org.robolectric.shadows.ShadowAccessibilityManager;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowContentResolver;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(
+        manifest = TestConfig.MANIFEST_PATH,
+        sdk = TestConfig.SDK_VERSION,
+        shadows = {
+                ShadowActivityWithLoadManager.class,
+                ShadowContextImplWithRegisterReceiver.class,
+                ShadowInputManager.class,
+                ShadowInputMethodManagerWithMethodList.class,
+                ShadowPackageMonitor.class,
+        }
+)
+public class DynamicIndexableContentMonitorTest {
+
+    private static final int USER_ID = 5678;
+    private static final int LOADER_ID = 1234;
+    private static final String A11Y_PACKAGE_1 = "a11y-1";
+    private static final String A11Y_PACKAGE_2 = "a11y-2";
+    private static final String IME_PACKAGE_1 = "ime-1";
+    private static final String IME_PACKAGE_2 = "ime-2";
+
+    private LoaderManager mLoaderManager = mock(LoaderManager.class);
+    private Index mIndex = mock(Index.class);
+
+    private Activity mActivity;
+    private InputManager mInputManager;
+
+    private ShadowContextImplWithRegisterReceiver mShadowContextImpl;
+    private ShadowActivityWithLoadManager mShadowActivity;
+    private ShadowAccessibilityManager mShadowAccessibilityManager;
+    private ShadowInputMethodManagerWithMethodList mShadowInputMethodManager;
+    private RobolectricPackageManager mRobolectricPackageManager;
+
+    private final DynamicIndexableContentMonitor mMonitor = new DynamicIndexableContentMonitor();
+
+    @Before
+    public void setUp() {
+        mActivity = Robolectric.buildActivity(Activity.class).get();
+        mInputManager = InputManager.getInstance();
+
+        // Robolectric shadows.
+        mShadowContextImpl = (ShadowContextImplWithRegisterReceiver) ShadowExtractor.extract(
+                ((Application) ShadowApplication.getInstance().getApplicationContext())
+                .getBaseContext());
+        mShadowActivity = (ShadowActivityWithLoadManager) ShadowExtractor.extract(mActivity);
+        mShadowAccessibilityManager = (ShadowAccessibilityManager) ShadowExtractor.extract(
+                mActivity.getSystemService(Context.ACCESSIBILITY_SERVICE));
+        mShadowInputMethodManager = (ShadowInputMethodManagerWithMethodList) ShadowExtractor
+                .extract(mActivity.getSystemService(Context.INPUT_METHOD_SERVICE));
+        mRobolectricPackageManager = RuntimeEnvironment.getRobolectricPackageManager();
+
+        // Setup shadows.
+        mShadowContextImpl.setSystemService(Context.PRINT_SERVICE, mock(PrintManager.class));
+        mShadowContextImpl.setSystemService(Context.INPUT_SERVICE, mInputManager);
+        mShadowActivity.setLoaderManager(mLoaderManager);
+        mShadowAccessibilityManager.setInstalledAccessibilityServiceList(Collections.emptyList());
+        mShadowInputMethodManager.setInputMethodList(Collections.emptyList());
+        mRobolectricPackageManager.setSystemFeature(PackageManager.FEATURE_PRINTING, true);
+        mRobolectricPackageManager.setSystemFeature(PackageManager.FEATURE_INPUT_METHODS, true);
+    }
+
+    @After
+    public void shutDown() {
+        DynamicIndexableContentMonitor.resetForTesting();
+        mRobolectricPackageManager.reset();
+    }
+
+    @Test
+    public void testLockedUser() {
+        mMonitor.register(mActivity, LOADER_ID, mIndex, false /* isUserUnlocked */);
+
+        // No loader procedure happens.
+        verify(mLoaderManager, never()).initLoader(
+                anyInt(), any(Bundle.class), any(LoaderManager.LoaderCallbacks.class));
+        // No indexing happens.
+        verify(mIndex, never()).updateFromClassNameResource(
+                anyString(), anyBoolean(), anyBoolean());
+
+        mMonitor.unregister(mActivity, LOADER_ID);
+
+        // No destroy loader should happen.
+        verify(mLoaderManager, never()).destroyLoader(anyInt());
+    }
+
+    @Test
+    public void testWithNoPrintingFeature() {
+        mRobolectricPackageManager.setSystemFeature(PackageManager.FEATURE_PRINTING, false);
+
+        mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */);
+
+        // No loader procedure happens.
+        verify(mLoaderManager, never()).initLoader(
+                anyInt(), any(Bundle.class), any(LoaderManager.LoaderCallbacks.class));
+        verifyNoIndexing(PrintSettingsFragment.class);
+
+        mMonitor.unregister(mActivity, LOADER_ID);
+
+        // No destroy loader should happen.
+        verify(mLoaderManager, never()).destroyLoader(anyInt());
+    }
+
+    @Test
+    public void testPrinterServiceIndex() {
+        mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */);
+
+        // Loader procedure happens.
+        verify(mLoaderManager, only()).initLoader(LOADER_ID, null, mMonitor);
+
+        // Loading print services happens.
+        final Loader<List<PrintServiceInfo>> loader =
+                mMonitor.onCreateLoader(LOADER_ID, null /* args */);
+        assertThat(loader).isInstanceOf(PrintServicesLoader.class);
+        verifyNoIndexing(PrintSettingsFragment.class);
+
+        mMonitor.onLoadFinished(loader, Collections.emptyList());
+
+        verifyIncrementalIndexing(PrintSettingsFragment.class);
+    }
+
+    @Test
+    public void testInputDevicesMonitor() {
+        mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */);
+
+        // Rebuild indexing should happen.
+        // CAVEAT: Currently InputMethodAndLanuageSettings may be indexed once for input devices and
+        // once for input methods.
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class, atLeastOnce());
+        // Input monitor should be registered to InputManager.
+        final InputManager.InputDeviceListener listener = extactInputDeviceListener();
+        assertThat(listener).isNotNull();
+
+        /*
+         * Nothing happens on successive register calls.
+         */
+        reset(mIndex);
+
+        mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */);
+
+        verifyNoIndexing(InputMethodAndLanguageSettings.class);
+        assertThat(extactInputDeviceListener()).isEqualTo(listener);
+
+        /*
+         * A device is added.
+         */
+        reset(mIndex);
+
+        listener.onInputDeviceAdded(1 /* deviceId */);
+
+        verifyIncrementalIndexing(InputMethodAndLanguageSettings.class);
+
+        /*
+         * A device is removed.
+         */
+        reset(mIndex);
+
+        listener.onInputDeviceRemoved(2 /* deviceId */);
+
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class);
+
+        /*
+         * A device is changed.
+         */
+        reset(mIndex);
+
+        listener.onInputDeviceChanged(3 /* deviceId */);
+
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class);
+    }
+
+    @Test
+    public void testAccessibilityServicesMonitor() throws Exception {
+        mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */);
+
+        final PackageMonitor packageMonitor = extractPackageMonitor();
+        assertThat(packageMonitor).isNotNull();
+
+        verifyRebuildIndexing(AccessibilitySettings.class);
+
+        /*
+         * When an accessibility service package is installed, incremental indexing happen.
+         */
+        installAccessibilityService(A11Y_PACKAGE_1);
+        reset(mIndex);
+
+        packageMonitor.onPackageAppeared(A11Y_PACKAGE_1, USER_ID);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyIncrementalIndexing(AccessibilitySettings.class);
+
+        /*
+         * When another accessibility service package is installed, incremental indexing happens.
+         */
+        installAccessibilityService(A11Y_PACKAGE_2);
+        reset(mIndex);
+
+        packageMonitor.onPackageAppeared(A11Y_PACKAGE_2, USER_ID);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyIncrementalIndexing(AccessibilitySettings.class);
+
+        /*
+         * When an accessibility service is disabled, rebuild indexing happens.
+         */
+        ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
+                A11Y_PACKAGE_1, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0 /* flags */);
+        reset(mIndex);
+
+        packageMonitor.onPackageModified(A11Y_PACKAGE_1);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyRebuildIndexing(AccessibilitySettings.class);
+
+        /*
+         * When an accessibility service is enabled, incremental indexing happens.
+         */
+        ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
+                A11Y_PACKAGE_1, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0 /* flags */);
+        reset(mIndex);
+
+        packageMonitor.onPackageModified(A11Y_PACKAGE_1);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyIncrementalIndexing(AccessibilitySettings.class);
+
+        /*
+         * When an accessibility service package is uninstalled, rebuild indexing happens.
+         */
+        uninstallAccessibilityService(A11Y_PACKAGE_1);
+        reset(mIndex);
+
+        packageMonitor.onPackageDisappeared(A11Y_PACKAGE_1, USER_ID);
+
+        verifyRebuildIndexing(AccessibilitySettings.class);
+
+        /*
+         * When an input method service package is installed, nothing happens.
+         */
+        installInputMethodService(IME_PACKAGE_1);
+        reset(mIndex);
+
+        packageMonitor.onPackageAppeared(IME_PACKAGE_1, USER_ID);
+
+        verifyNoIndexing(AccessibilitySettings.class);
+    }
+
+    @Test
+    public void testInputMethodServicesMonitor() throws Exception {
+        mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */);
+
+        final PackageMonitor packageMonitor = extractPackageMonitor();
+        assertThat(packageMonitor).isNotNull();
+
+        // CAVEAT: Currently InputMethodAndLanuageSettings may be indexed once for input devices and
+        // once for input methods.
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class, atLeastOnce());
+
+        /*
+         * When an input method service package is installed, incremental indexing happen.
+         */
+        installInputMethodService(IME_PACKAGE_1);
+        reset(mIndex);
+
+        packageMonitor.onPackageAppeared(IME_PACKAGE_1, USER_ID);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyIncrementalIndexing(InputMethodAndLanguageSettings.class);
+
+        /*
+         * When another input method service package is installed, incremental indexing happens.
+         */
+        installInputMethodService(IME_PACKAGE_2);
+        reset(mIndex);
+
+        packageMonitor.onPackageAppeared(IME_PACKAGE_2, USER_ID);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyIncrementalIndexing(InputMethodAndLanguageSettings.class);
+
+        /*
+         * When an input method service is disabled, rebuild indexing happens.
+         */
+        ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
+                IME_PACKAGE_1, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0 /* flags */);
+        reset(mIndex);
+
+        packageMonitor.onPackageModified(IME_PACKAGE_1);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class);
+
+        /*
+         * When an input method service is enabled, incremental indexing happens.
+         */
+        ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
+                IME_PACKAGE_1, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0 /* flags */);
+        reset(mIndex);
+
+        packageMonitor.onPackageModified(IME_PACKAGE_1);
+        Robolectric.flushBackgroundThreadScheduler();
+
+        verifyIncrementalIndexing(InputMethodAndLanguageSettings.class);
+
+        /*
+         * When an input method service package is uninstalled, rebuild indexing happens.
+         */
+        uninstallInputMethodService(IME_PACKAGE_1);
+        reset(mIndex);
+
+        packageMonitor.onPackageDisappeared(IME_PACKAGE_1, USER_ID);
+
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class);
+
+        /*
+         * When an accessibility service package is installed, nothing happens.
+         */
+        installAccessibilityService(A11Y_PACKAGE_1);
+        reset(mIndex);
+
+        packageMonitor.onPackageAppeared(A11Y_PACKAGE_1, USER_ID);
+
+        verifyNoIndexing(InputMethodAndLanguageSettings.class);
+    }
+
+    @Test
+    public void testUserDictionaryChangeMonitor() throws Exception {
+        mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */);
+
+        // Content observer should be registered.
+        final ContentObserver observer = extractContentObserver(UserDictionary.Words.CONTENT_URI);
+        assertThat(observer).isNotNull();
+
+        // CAVEAT: Currently InputMethodAndLanuageSettings may be indexed once for input devices and
+        // once for input methods.
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class, atLeastOnce());
+
+        /*
+         * When user dictionary content is changed, rebuild indexing happens.
+         */
+        reset(mIndex);
+
+        observer.onChange(false /* selfChange */, UserDictionary.Words.CONTENT_URI);
+
+        verifyRebuildIndexing(InputMethodAndLanguageSettings.class);
+    }
+
+    /*
+     * Verification helpers.
+     */
+
+    private void verifyNoIndexing(Class<?> indexingClass) {
+        verify(mIndex, never()).updateFromClassNameResource(eq(indexingClass.getName()),
+                anyBoolean(), anyBoolean());
+    }
+
+    private void verifyRebuildIndexing(Class<?> indexingClass) {
+        verifyRebuildIndexing(indexingClass, times(1));
+    }
+
+    private void verifyRebuildIndexing(Class<?> indexingClass, VerificationMode verificationMode) {
+        verify(mIndex, verificationMode).updateFromClassNameResource(indexingClass.getName(),
+                true /* rebuild */, true /* includeInSearchResults */);
+        verify(mIndex, never()).updateFromClassNameResource(indexingClass.getName(),
+                false /* rebuild */, true /* includeInSearchResults */);
+    }
+
+    private void verifyIncrementalIndexing(Class<?> indexingClass) {
+        verify(mIndex, times(1)).updateFromClassNameResource(indexingClass.getName(),
+                false /* rebuild */, true /* includeInSearchResults */);
+        verify(mIndex, never()).updateFromClassNameResource(indexingClass.getName(),
+                true /* rebuild */, true /* includeInSearchResults */);
+    }
+
+    /*
+     * Testing helper methods.
+     */
+
+    private InputManager.InputDeviceListener extactInputDeviceListener() {
+        List<InputManager.InputDeviceListener> listeners = ((ShadowInputManager) ShadowExtractor
+                .extract(mInputManager))
+                .getRegisteredInputDeviceListeners();
+        InputManager.InputDeviceListener inputDeviceListener = null;
+        for (InputManager.InputDeviceListener listener : listeners) {
+            if (isUnderTest(listener)) {
+                if (inputDeviceListener != null) {
+                    assertThat(listener).isEqualTo(inputDeviceListener);
+                } else {
+                    inputDeviceListener = listener;
+                }
+            }
+        }
+        return inputDeviceListener;
+    }
+
+    private PackageMonitor extractPackageMonitor() {
+        List<ShadowApplication.Wrapper> receivers = ShadowApplication.getInstance()
+                .getRegisteredReceivers();
+        PackageMonitor packageMonitor = null;
+        for (ShadowApplication.Wrapper wrapper : receivers) {
+            BroadcastReceiver receiver = wrapper.getBroadcastReceiver();
+            if (isUnderTest(receiver) && receiver instanceof PackageMonitor) {
+                if (packageMonitor != null) {
+                    assertThat(receiver).isEqualTo(packageMonitor);
+                } else {
+                    packageMonitor = (PackageMonitor) receiver;
+                }
+            }
+        }
+        return packageMonitor;
+    }
+
+    private ContentObserver extractContentObserver(Uri uri) {
+        ShadowContentResolver contentResolver = (ShadowContentResolver) ShadowExtractor
+                .extract(mActivity.getContentResolver());
+        Collection<ContentObserver> observers = contentResolver.getContentObservers(uri);
+        ContentObserver contentObserver = null;
+        for (ContentObserver observer : observers) {
+            if (isUnderTest(observer)) {
+                if (contentObserver != null) {
+                    assertThat(observer).isEqualTo(contentObserver);
+                } else {
+                    contentObserver = observer;
+                }
+            }
+        }
+        return contentObserver;
+    }
+
+    private void installAccessibilityService(String packageName) throws Exception {
+        final AccessibilityServiceInfo serviceToAdd = buildAccessibilityServiceInfo(packageName);
+
+        final List<AccessibilityServiceInfo> services = new ArrayList<>();
+        services.addAll(mShadowAccessibilityManager.getInstalledAccessibilityServiceList());
+        services.add(serviceToAdd);
+        mShadowAccessibilityManager.setInstalledAccessibilityServiceList(services);
+
+        final Intent intent = DynamicIndexableContentMonitor
+                .getAccessibilityServiceIntent(packageName);
+        mRobolectricPackageManager.addResolveInfoForIntent(intent, serviceToAdd.getResolveInfo());
+        mRobolectricPackageManager.addPackage(packageName);
+    }
+
+    private void uninstallAccessibilityService(String packageName) throws Exception {
+        final AccessibilityServiceInfo serviceToRemove = buildAccessibilityServiceInfo(packageName);
+
+        final List<AccessibilityServiceInfo> services = new ArrayList<>();
+        services.addAll(mShadowAccessibilityManager.getInstalledAccessibilityServiceList());
+        services.remove(serviceToRemove);
+        mShadowAccessibilityManager.setInstalledAccessibilityServiceList(services);
+
+        final Intent intent = DynamicIndexableContentMonitor
+                .getAccessibilityServiceIntent(packageName);
+        mRobolectricPackageManager.removeResolveInfosForIntent(intent, packageName);
+        mRobolectricPackageManager.removePackage(packageName);
+    }
+
+    private void installInputMethodService(String packageName) throws Exception {
+        final ResolveInfo resolveInfoToAdd = buildResolveInfo(packageName, "imeService");
+        final InputMethodInfo serviceToAdd = buildInputMethodInfo(resolveInfoToAdd);
+
+        final List<InputMethodInfo> services = new ArrayList<>();
+        services.addAll(mShadowInputMethodManager.getInputMethodList());
+        services.add(serviceToAdd);
+        mShadowInputMethodManager.setInputMethodList(services);
+
+        final Intent intent = DynamicIndexableContentMonitor.getIMEServiceIntent(packageName);
+        mRobolectricPackageManager.addResolveInfoForIntent(intent, resolveInfoToAdd);
+        mRobolectricPackageManager.addPackage(packageName);
+    }
+
+    private void uninstallInputMethodService(String packageName) throws Exception {
+        final ResolveInfo resolveInfoToRemove = buildResolveInfo(packageName, "imeService");
+        final InputMethodInfo serviceToRemove = buildInputMethodInfo(resolveInfoToRemove);
+
+        final List<InputMethodInfo> services = new ArrayList<>();
+        services.addAll(mShadowInputMethodManager.getInputMethodList());
+        services.remove(serviceToRemove);
+        mShadowInputMethodManager.setInputMethodList(services);
+
+        final Intent intent = DynamicIndexableContentMonitor.getIMEServiceIntent(packageName);
+        mRobolectricPackageManager.removeResolveInfosForIntent(intent, packageName);
+        mRobolectricPackageManager.removePackage(packageName);
+    }
+
+    private AccessibilityServiceInfo buildAccessibilityServiceInfo(String packageName)
+            throws IOException, XmlPullParserException {
+        return new AccessibilityServiceInfo(
+                buildResolveInfo(packageName, "A11yService"), mActivity);
+    }
+
+    private static InputMethodInfo buildInputMethodInfo(ResolveInfo resolveInfo) {
+        return new InputMethodInfo(resolveInfo, false /* isAuxIme */, "SettingsActivity",
+                null /* subtypes */,  0 /* defaultResId */, false /* forceDefault */);
+    }
+
+    private static ResolveInfo buildResolveInfo(String packageName, String className) {
+        final ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.serviceInfo = new ServiceInfo();
+        resolveInfo.serviceInfo.packageName = packageName;
+        resolveInfo.serviceInfo.name = className;
+        // To workaround that RobolectricPackageManager.removeResolveInfosForIntent() only works
+        // for activity/broadcast resolver.
+        resolveInfo.activityInfo = new ActivityInfo();
+        resolveInfo.activityInfo.packageName = packageName;
+        resolveInfo.activityInfo.name = className;
+
+        return resolveInfo;
+    }
+
+    private static boolean isUnderTest(Object object) {
+        return object.getClass().getName().startsWith(
+                DynamicIndexableContentMonitor.class.getName());
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowActivityWithLoadManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowActivityWithLoadManager.java
new file mode 100644
index 0000000..0125b77
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowActivityWithLoadManager.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.testutils.shadow;
+
+import android.app.Activity;
+import android.app.LoaderManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowActivity;
+
+/*
+ * Shadow for {@link Activity} that has LoadManager accessors.
+ */
+@Implements(Activity.class)
+public class ShadowActivityWithLoadManager extends ShadowActivity {
+
+    private LoaderManager mLoaderManager;
+
+    @Implementation
+    public LoaderManager getLoaderManager() {
+        return mLoaderManager;
+    }
+
+    // Non-Android setter.
+    public void setLoaderManager(LoaderManager loaderManager) {
+        mLoaderManager = loaderManager;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContextImplWithRegisterReceiver.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContextImplWithRegisterReceiver.java
new file mode 100644
index 0000000..c1f8293
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowContextImplWithRegisterReceiver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.testutils.shadow;
+
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Handler;
+import android.os.UserHandle;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowContextImpl;
+
+/*
+ * Shadow for {@link ContextImpl} that has registerReceiverAsUser method.
+ */
+@Implements(className = ShadowContextImpl.CLASS_NAME)
+public class ShadowContextImplWithRegisterReceiver extends ShadowContextImpl {
+
+    @Implementation
+    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+            IntentFilter filter, String broadcastPermission, Handler scheduler) {
+        return super.registerReceiver(receiver, filter, broadcastPermission, scheduler);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowInputManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowInputManager.java
new file mode 100644
index 0000000..5b09645
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowInputManager.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.testutils.shadow;
+
+import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
+
+import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/*
+ * Shadow for {@ InputManager} that has assessors for registered {@link InputDeviceListener}s.
+ */
+@Implements(value = InputManager.class, callThroughByDefault = false)
+public class ShadowInputManager {
+
+    private ArrayList<InputManager.InputDeviceListener> mInputDeviceListeners;
+
+    @Implementation
+    public void __constructor__(IInputManager service) {
+        mInputDeviceListeners = new ArrayList<>();
+    }
+
+    @Implementation
+    public static InputManager getInstance() {
+        return ReflectionHelpers.callConstructor(
+                InputManager.class,
+                from(IInputManager.class, null));
+    }
+
+    @Implementation
+    public void registerInputDeviceListener(InputManager.InputDeviceListener listener,
+            Handler handler) {
+        // TODO: Use handler.
+        if (!mInputDeviceListeners.contains(listener)) {
+            mInputDeviceListeners.add(listener);
+        }
+    }
+
+    @Implementation
+    public void unregisterInputDeviceListener(InputManager.InputDeviceListener listener) {
+        if (mInputDeviceListeners.contains(listener)) {
+            mInputDeviceListeners.remove(listener);
+        }
+    }
+
+    // Non-Android accessor.
+    public List<InputManager.InputDeviceListener> getRegisteredInputDeviceListeners() {
+        return Collections.unmodifiableList(mInputDeviceListeners);
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowInputMethodManagerWithMethodList.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowInputMethodManagerWithMethodList.java
new file mode 100644
index 0000000..0e59fec
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowInputMethodManagerWithMethodList.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.testutils.shadow;
+
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowInputMethodManager;
+
+import java.util.Collections;
+import java.util.List;
+
+/*
+ * Shadow for {@link InputMethodManager} that has accessors for installed input methods.
+ */
+@Implements(InputMethodManager.class)
+public class ShadowInputMethodManagerWithMethodList extends ShadowInputMethodManager {
+
+    private List<InputMethodInfo> mInputMethodInfos = Collections.emptyList();
+
+    @Implementation
+    public static InputMethodManager getInstance() {
+        return ShadowInputMethodManager.peekInstance();
+    }
+
+    @Implementation
+    public List<InputMethodInfo> getInputMethodList() {
+        return mInputMethodInfos;
+    }
+
+    // Non-Android setter.
+    public void setInputMethodList(List<InputMethodInfo> inputMethodInfos) {
+        mInputMethodInfos = inputMethodInfos;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPackageMonitor.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPackageMonitor.java
new file mode 100644
index 0000000..b93b035
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowPackageMonitor.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.settings.testutils.shadow;
+
+import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.UserHandle;
+
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.BackgroundThread;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.internal.Shadow;
+import org.robolectric.internal.ShadowExtractor;
+import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowMessageQueue;
+
+/*
+ * Shadow for hidden {@link PackageMonitor}.
+ */
+@Implements(value = PackageMonitor.class, isInAndroidSdk = false)
+public class ShadowPackageMonitor {
+
+    @RealObject
+    private PackageMonitor mPackageMonitor;
+
+    @Implementation
+    public void register(Context context, Looper thread, UserHandle user, boolean externalStorage) {
+        // Call through to @RealObject's method.
+        Shadow.directlyOn(mPackageMonitor, PackageMonitor.class, "register",
+                from(Context.class, context), from(Looper.class, thread),
+                from(UserHandle.class, user), from(Boolean.TYPE, externalStorage));
+        // When <code>thread</code> is null, the {@link BackgroundThread} is used. Here we have to
+        // setup background Robolectric scheduler for it.
+        if (thread == null) {
+            setupBackgroundThreadScheduler();
+        }
+    }
+
+    private static void setupBackgroundThreadScheduler() {
+        ShadowMessageQueue shadowMessageQueue = ((ShadowMessageQueue) ShadowExtractor.extract(
+                BackgroundThread.getHandler().getLooper().getQueue()));
+        shadowMessageQueue.setScheduler(
+                ShadowApplication.getInstance().getBackgroundThreadScheduler());
+    }
+}
