diff --git a/res/xml/available_virtual_keyboard.xml b/res/xml/available_virtual_keyboard.xml
new file mode 100644
index 00000000000..9a0b3c62ab1
--- /dev/null
+++ b/res/xml/available_virtual_keyboard.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 928eae1114d..f9b849eb796 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -60,7 +60,6 @@ import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.dashboard.DashboardSummary;
import com.android.settings.development.DevelopmentSettings;
import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.search.DynamicIndexableContentMonitor;
import com.android.settings.search.SearchActivity;
import com.android.settings.wfd.WifiDisplaySettings;
import com.android.settings.widget.SwitchBar;
@@ -78,8 +77,6 @@ public class SettingsActivity extends SettingsDrawerActivity
private static final String LOG_TAG = "Settings";
- public static final int LOADER_ID_INDEXABLE_CONTENT_MONITOR = 1;
-
// Constants for state save/restore
private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
@VisibleForTesting
@@ -184,8 +181,6 @@ public class SettingsActivity extends SettingsDrawerActivity
}
};
- private DynamicIndexableContentMonitor mDynamicIndexableContentMonitor;
-
private SwitchBar mSwitchBar;
private Button mNextButton;
@@ -538,10 +533,6 @@ public class SettingsActivity extends SettingsDrawerActivity
new IntentFilter(DevelopmentSettingsEnabler.DEVELOPMENT_SETTINGS_CHANGED_ACTION));
registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
- if (mDynamicIndexableContentMonitor == null) {
- mDynamicIndexableContentMonitor = new DynamicIndexableContentMonitor();
- }
- mDynamicIndexableContentMonitor.register(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
updateTilesList();
}
@@ -552,9 +543,6 @@ public class SettingsActivity extends SettingsDrawerActivity
LocalBroadcastManager.getInstance(this).unregisterReceiver(mDevelopmentSettingsListener);
mDevelopmentSettingsListener = null;
unregisterReceiver(mBatteryInfoReceiver);
- if (mDynamicIndexableContentMonitor != null) {
- mDynamicIndexableContentMonitor.unregister(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
- }
}
@Override
diff --git a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
index a7862ae2401..48b0b4ada4f 100644
--- a/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/AvailableVirtualKeyboardFragment.java
@@ -21,7 +21,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -31,17 +30,15 @@ import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.support.v7.preference.PreferenceScreen;
+import android.provider.SearchIndexableResource;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
import com.android.settingslib.inputmethod.InputMethodPreference;
import com.android.settingslib.inputmethod.InputMethodSettingValuesWrapper;
@@ -60,10 +57,9 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
@Override
public void onCreatePreferences(Bundle bundle, String s) {
+ addPreferencesFromResource(R.xml.available_virtual_keyboard);
Activity activity = getActivity();
- PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(activity);
- screen.setTitle(activity.getString(R.string.available_virtual_keyboard_category));
- setPreferenceScreen(screen);
+
mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(activity);
mImm = activity.getSystemService(InputMethodManager.class);
mDpm = activity.getSystemService(DevicePolicyManager.class);
@@ -105,7 +101,7 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
}
try {
return packageManager.getDrawable(packageName, resId, applicationInfo);
- } catch (Exception e){
+ } catch (Exception e) {
return null;
}
}
@@ -172,48 +168,16 @@ public final class AvailableVirtualKeyboardFragment extends SettingsPreferenceFr
}
}
- private static List getAllSubtypesOf(final InputMethodInfo imi) {
- final int subtypeCount = imi.getSubtypeCount();
- final List allSubtypes = new ArrayList<>(subtypeCount);
- for (int index = 0; index < subtypeCount; index++) {
- allSubtypes.add(imi.getSubtypeAt(index));
- }
- return allSubtypes;
- }
-
- static List buildSearchIndexOfInputMethods(final Context context,
- final List inputMethods, final String screenTitle) {
- final List indexes = new ArrayList<>();
- for (int i = 0; i < inputMethods.size(); i++) {
- final InputMethodInfo imi = inputMethods.get(i);
- final ServiceInfo serviceInfo = imi.getServiceInfo();
- final SearchIndexableRaw index = new SearchIndexableRaw(context);
- index.key = new ComponentName(serviceInfo.packageName, serviceInfo.name)
- .flattenToString();
- index.title = imi.loadLabel(context.getPackageManager()).toString();
- index.summaryOn = index.summaryOff = InputMethodAndSubtypeUtil
- .getSubtypeLocaleNameListAsSentence(getAllSubtypesOf(imi), context, imi);
- index.screenTitle = screenTitle;
- indexes.add(index);
- }
- return indexes;
- }
-
- public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
- @Override
- public List getRawDataToIndex(Context context, boolean enabled) {
- final InputMethodManager imm = context.getSystemService(InputMethodManager.class);
- final List enabledInputMethods = imm.getEnabledInputMethodList();
- final List disabledInputMethods = new ArrayList<>();
- for (final InputMethodInfo imi : imm.getInputMethodList()) {
- if (!enabledInputMethods.contains(imi)) {
- disabledInputMethods.add(imi);
+ @Override
+ public List getXmlResourcesToIndex(Context context,
+ boolean enabled) {
+ List res = new ArrayList<>();
+ SearchIndexableResource index = new SearchIndexableResource(context);
+ index.xmlResId = R.xml.available_virtual_keyboard;
+ res.add(index);
+ return res;
}
- }
- final String screenTitle = context.getString(
- R.string.available_virtual_keyboard_category);
- return buildSearchIndexOfInputMethods(context, disabledInputMethods, screenTitle);
- }
- };
+ };
}
diff --git a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
index 42eff159747..83d501d0a35 100644
--- a/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
@@ -31,6 +31,7 @@ import android.hardware.input.KeyboardLayout;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
+import android.provider.SearchIndexableResource;
import android.provider.Settings.Secure;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
@@ -51,11 +52,11 @@ import com.android.settings.Settings;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
import java.text.Collator;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -288,6 +289,7 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
final PhysicalKeyboardFragment mPhysicalKeyboardFragment;
@NonNull
final List mHardKeyboards;
+
public Callbacks(
@NonNull Context context,
@NonNull PhysicalKeyboardFragment physicalKeyboardFragment,
@@ -532,43 +534,14 @@ public final class PhysicalKeyboardFragment extends SettingsPreferenceFragment
}
}
- public static List getPhysicalFullKeyboards() {
- List keyboards = null;
- for (final int deviceId : InputDevice.getDeviceIds()) {
- final InputDevice device = InputDevice.getDevice(deviceId);
- if (device != null && !device.isVirtual() && device.isFullKeyboard()) {
- if (keyboards == null) keyboards = new ArrayList<>();
- keyboards.add(device);
- }
- }
- return (keyboards == null) ? Collections.emptyList() : keyboards;
- }
-
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
- @Override
- public List getRawDataToIndex(Context context, boolean enabled) {
- final InputManager inputManager = (InputManager) context.getSystemService(
- Context.INPUT_SERVICE);
- final String screenTitle = context.getString(R.string.physical_keyboard_title);
- final List indexes = new ArrayList<>();
- for (final InputDevice device : getPhysicalFullKeyboards()) {
- final String keyboardLayoutDescriptor = inputManager
- .getCurrentKeyboardLayoutForInputDevice(device.getIdentifier());
- final KeyboardLayout keyboardLayout = (keyboardLayoutDescriptor != null)
- ? inputManager.getKeyboardLayout(keyboardLayoutDescriptor) : null;
- final String summary = (keyboardLayout != null)
- ? keyboardLayout.toString()
- : context.getString(R.string.keyboard_layout_default_label);
- final SearchIndexableRaw index = new SearchIndexableRaw(context);
- index.key = device.getName();
- index.title = device.getName();
- index.summaryOn = summary;
- index.summaryOff = summary;
- index.screenTitle = screenTitle;
- indexes.add(index);
- }
- return indexes;
- }
- };
+ @Override
+ public List getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.physical_keyboard_settings;
+ return Arrays.asList(sir);
+ }
+ };
}
diff --git a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
index 7b7c5992e81..fbe9690bb6d 100644
--- a/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
+++ b/src/com/android/settings/inputmethod/VirtualKeyboardFragment.java
@@ -23,6 +23,7 @@ import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.provider.SearchIndexableResource;
import android.support.v7.preference.Preference;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -33,14 +34,12 @@ import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
import com.android.settingslib.inputmethod.InputMethodPreference;
import java.text.Collator;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.Arrays;
import java.util.List;
public final class VirtualKeyboardFragment extends SettingsPreferenceFragment implements Indexable {
@@ -121,13 +120,19 @@ public final class VirtualKeyboardFragment extends SettingsPreferenceFragment im
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
- @Override
- public List getRawDataToIndex(Context context, boolean enabled) {
- final InputMethodManager imm = context.getSystemService(InputMethodManager.class);
- final List enabledInputMethods = imm.getEnabledInputMethodList();
- final String screenTitle = context.getString(R.string.virtual_keyboard_category);
- return AvailableVirtualKeyboardFragment
- .buildSearchIndexOfInputMethods(context, enabledInputMethods, screenTitle);
- }
- };
+ @Override
+ public List getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.virtual_keyboard_settings;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List getNonIndexableKeys(Context context) {
+ final List keys = super.getNonIndexableKeys(context);
+ keys.add("add_virtual_keyboard_screen");
+ return keys;
+ }
+ };
}
diff --git a/src/com/android/settings/language/LanguageAndInputSettings.java b/src/com/android/settings/language/LanguageAndInputSettings.java
index fbcb02f5cbc..4affc6edbc6 100644
--- a/src/com/android/settings/language/LanguageAndInputSettings.java
+++ b/src/com/android/settings/language/LanguageAndInputSettings.java
@@ -52,6 +52,7 @@ public class LanguageAndInputSettings extends DashboardFragment {
private static final String TAG = "LangAndInputSettings";
private static final String KEY_TEXT_TO_SPEECH = "tts_settings_summary";
+ private static final String KEY_PHYSICAL_KEYBOARD = "physical_keyboard_pref";
@Override
public int getMetricsCategory() {
@@ -174,6 +175,7 @@ public class LanguageAndInputSettings extends DashboardFragment {
List keys = super.getNonIndexableKeys(context);
// Duplicates in summary and details pages.
keys.add(KEY_TEXT_TO_SPEECH);
+ keys.add(KEY_PHYSICAL_KEYBOARD);
return keys;
}
diff --git a/src/com/android/settings/search/DynamicIndexableContentMonitor.java b/src/com/android/settings/search/DynamicIndexableContentMonitor.java
deleted file mode 100644
index a0e3c021dd7..00000000000
--- a/src/com/android/settings/search/DynamicIndexableContentMonitor.java
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Copyright (C) 2014 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 android.accessibilityservice.AccessibilityService;
-import android.app.Activity;
-import android.app.LoaderManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.Loader;
-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.os.UserHandle;
-import android.os.UserManager;
-import android.print.PrintManager;
-import android.print.PrintServicesLoader;
-import android.printservice.PrintServiceInfo;
-import android.provider.Settings;
-import android.provider.UserDictionary;
-import android.support.annotation.Nullable;
-import android.support.annotation.VisibleForTesting;
-import android.util.Log;
-import android.view.inputmethod.InputMethod;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
-
-import com.android.internal.content.PackageMonitor;
-import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
-import com.android.settings.inputmethod.PhysicalKeyboardFragment;
-import com.android.settings.inputmethod.VirtualKeyboardFragment;
-import com.android.settings.language.LanguageAndInputSettings;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.print.PrintSettingsFragment;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public final class DynamicIndexableContentMonitor implements
- LoaderManager.LoaderCallbacks> {
- // 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;
- // A PackageMonitor shared among Settings activities.
- private static final PackageChangeMonitor PACKAGE_CHANGE_MONITOR = new PackageChangeMonitor();
-
- // Null if not initialized.
- @Nullable private DatabaseIndexingManager mIndexManager;
- private Context mContext;
- private boolean mHasFeaturePrinting;
-
- @VisibleForTesting
- static Intent getAccessibilityServiceIntent(String packageName) {
- final Intent intent = new Intent(AccessibilityService.SERVICE_INTERFACE);
- intent.setPackage(packageName);
- return intent;
- }
-
- @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();
- InputMethodServicesMonitor.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.
- * mIndex
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) {
- final boolean isUserUnlocked = activity
- .getSystemService(UserManager.class)
- .isUserUnlocked();
- register(activity, loaderId, FeatureFactory.getFactory(activity)
- .getSearchFeatureProvider().getIndexingManager(activity), isUserUnlocked);
- }
-
- /**
- * For testing to inject {@link DatabaseIndexingManager} 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, DatabaseIndexingManager indexManager,
- boolean isUserUnlocked) {
- if (!isUserUnlocked) {
- Log.w(TAG, "Skipping content monitoring because user is locked");
- return;
- }
- final Context context = activity.getApplicationContext();
- mContext = context;
- mIndexManager = indexManager;
-
- PACKAGE_CHANGE_MONITOR.registerMonitor(context);
- mHasFeaturePrinting = context.getPackageManager()
- .hasSystemFeature(PackageManager.FEATURE_PRINTING);
- if (mHasFeaturePrinting) {
- activity.getLoaderManager().initLoader(loaderId, null /* args */, this /* callbacks */);
- }
-
- // Watch for input device changes.
- InputDevicesMonitor.getInstance().initialize(context, mIndexManager);
-
- // Start tracking packages.
- InputMethodServicesMonitor.getInstance().initialize(context, mIndexManager);
- }
-
- /**
- * 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 (mIndexManager == null) return;
-
- PACKAGE_CHANGE_MONITOR.unregisterMonitor();
- if (mHasFeaturePrinting) {
- activity.getLoaderManager().destroyLoader(loaderId);
- }
- }
-
- @Override
- public Loader> onCreateLoader(int id, Bundle args) {
- return new PrintServicesLoader(
- (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE), mContext,
- PrintManager.ALL_SERVICES);
- }
-
- @Override
- public void onLoadFinished(Loader> loader,
- List services) {
- mIndexManager.updateFromClassNameResource(PrintSettingsFragment.class.getName(),
- true /* includeInSearchResults */);
- }
-
- @Override
- public void onLoaderReset(Loader> loader) {
- // nothing to do
- }
-
- // A singleton that monitors input devices changes and updates indexes of physical keyboards.
- private static class InputDevicesMonitor implements InputManager.InputDeviceListener {
-
- // Null if not initialized.
- @Nullable private DatabaseIndexingManager mIndexManager;
- 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 (mIndexManager != null) {
- mInputManager.unregisterInputDeviceListener(this /* listener */);
- }
- mIndexManager = null;
- }
-
- synchronized void initialize(Context context, DatabaseIndexingManager indexManager) {
- if (mIndexManager != null) return;
- mIndexManager = indexManager;
- mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
- buildIndex();
-
- // Watch for input device changes.
- mInputManager.registerInputDeviceListener(this /* listener */, null /* handler */);
- }
-
- private void buildIndex() {
- mIndexManager.updateFromClassNameResource(PhysicalKeyboardFragment.class.getName(),
- true /* includeInSearchResults */);
- }
-
- @Override
- public void onInputDeviceAdded(int deviceId) {
- buildIndex();
- }
-
- @Override
- public void onInputDeviceRemoved(int deviceId) {
- buildIndex();
- }
-
- @Override
- public void onInputDeviceChanged(int deviceId) {
- buildIndex();
- }
- }
-
- // 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. Guarded by {@link #mLock}.
- @Nullable private PackageManager mPackageManager;
- private final Object mLock = new Object();
-
- public void registerMonitor(Context context) {
- synchronized (mLock) {
- if (mPackageManager != null) {
- return;
- }
- mPackageManager = context.getPackageManager();
-
- // 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.
- super.register(context, null /* thread */, UserHandle.CURRENT, false);
- }
- }
-
- public void unregisterMonitor() {
- synchronized (mLock) {
- if (mPackageManager == null) {
- return;
- }
- super.unregister();
- mPackageManager = null;
- }
- }
-
- // Covers installed, appeared external storage with the package, upgraded.
- @Override
- public void onPackageAppeared(String packageName, int reason) {
- postPackageAvailable(packageName);
- }
-
- // Covers uninstalled, removed external storage with the package.
- @Override
- public void onPackageDisappeared(String packageName, int reason) {
- 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(() -> {
- InputMethodServicesMonitor.getInstance().onPackageAvailable(packageName);
- }, DELAY_PROCESS_PACKAGE_CHANGE);
- }
-
- private void postPackageUnavailable(final String packageName) {
- getRegisteredHandler().postDelayed(() -> {
- InputMethodServicesMonitor.getInstance().onPackageUnavailable(packageName);
- }, DELAY_PROCESS_PACKAGE_CHANGE);
- }
- }
-
- // 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 {
-
- private static final Uri ENABLED_INPUT_METHODS_CONTENT_URI =
- Settings.Secure.getUriFor(Settings.Secure.ENABLED_INPUT_METHODS);
-
- // Null if not initialized.
- @Nullable private DatabaseIndexingManager mIndexManager;
- private PackageManager mPackageManager;
- private ContentResolver mContentResolver;
- private final List 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 (mIndexManager != null) {
- mContentResolver.unregisterContentObserver(this /* observer */);
- }
- mIndexManager = null;
- }
-
- synchronized void initialize(Context context, DatabaseIndexingManager indexManager) {
- final boolean hasFeatureIme = context.getPackageManager()
- .hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS);
- if (!hasFeatureIme) return;
-
- if (mIndexManager != null) return;
- mIndexManager = indexManager;
- mPackageManager = context.getPackageManager();
- mContentResolver = context.getContentResolver();
- mInputMethodServices.clear();
- // Build index of {@link UserDictionary}.
- buildIndex(LanguageAndInputSettings.class);
- // Build index of IMEs.
- buildIndex(VirtualKeyboardFragment.class);
- buildIndex(AvailableVirtualKeyboardFragment.class);
-
- // 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);
- }
- }
-
- // TODO: Implements by JobScheduler with TriggerContentUri parameters.
- // Watch for related content URIs.
- mContentResolver.registerContentObserver(UserDictionary.Words.CONTENT_URI,
- true /* notifyForDescendants */, this /* observer */);
- // Watch for changing enabled IMEs.
- mContentResolver.registerContentObserver(ENABLED_INPUT_METHODS_CONTENT_URI,
- false /* notifyForDescendants */, this /* observer */);
- }
-
- private void buildIndex(Class> indexClass) {
- mIndexManager.updateFromClassNameResource(indexClass.getName(),
- true /* includeInSearchResults */);
- }
-
- synchronized void onPackageAvailable(String packageName) {
- if (mIndexManager == null) return;
- if (mInputMethodServices.contains(packageName)) return;
-
- final Intent intent = getIMEServiceIntent(packageName);
- final List services = mPackageManager
- .queryIntentServices(intent, 0 /* flags */);
- if (services == null || services.isEmpty()) return;
- mInputMethodServices.add(packageName);
- buildIndex(VirtualKeyboardFragment.class);
- buildIndex(AvailableVirtualKeyboardFragment.class);
- }
-
- synchronized void onPackageUnavailable(String packageName) {
- if (mIndexManager == null) return;
- if (!mInputMethodServices.remove(packageName)) return;
- buildIndex(VirtualKeyboardFragment.class);
- buildIndex(AvailableVirtualKeyboardFragment.class);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (ENABLED_INPUT_METHODS_CONTENT_URI.equals(uri)) {
- buildIndex(VirtualKeyboardFragment.class);
- buildIndex(AvailableVirtualKeyboardFragment.class);
- } else if (UserDictionary.Words.CONTENT_URI.equals(uri)) {
- buildIndex(LanguageAndInputSettings.class);
- }
- }
- }
-}
diff --git a/src/com/android/settings/search/InputDeviceResultLoader.java b/src/com/android/settings/search/InputDeviceResultLoader.java
new file mode 100644
index 00000000000..61e1ad1671e
--- /dev/null
+++ b/src/com/android/settings/search/InputDeviceResultLoader.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2017 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 android.content.Context.INPUT_METHOD_SERVICE;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.hardware.input.InputManager;
+import android.hardware.input.KeyboardLayout;
+import android.support.annotation.VisibleForTesting;
+import android.view.InputDevice;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.settings.R;
+import com.android.settings.dashboard.SiteMapManager;
+import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
+import com.android.settings.inputmethod.PhysicalKeyboardFragment;
+import com.android.settings.utils.AsyncLoader;
+import com.android.settingslib.inputmethod.InputMethodAndSubtypeUtil;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Search result for input devices (physical/virtual keyboard, game controllers, etc)
+ */
+public class InputDeviceResultLoader extends AsyncLoader> {
+ private static final int NAME_NO_MATCH = -1;
+
+ @VisibleForTesting
+ static final String PHYSICAL_KEYBOARD_FRAGMENT = PhysicalKeyboardFragment.class.getName();
+ @VisibleForTesting
+ static final String VIRTUAL_KEYBOARD_FRAGMENT =
+ AvailableVirtualKeyboardFragment.class.getName();
+
+ private final SiteMapManager mSiteMapManager;
+ private final InputManager mInputManager;
+ private final InputMethodManager mImm;
+ private final PackageManager mPackageManager;
+ @VisibleForTesting
+ final String mQuery;
+
+ private List mPhysicalKeyboardBreadcrumb;
+ private List mVirtualKeyboardBreadcrumb;
+
+ public InputDeviceResultLoader(Context context, String query, SiteMapManager mapManager) {
+ super(context);
+ mQuery = query;
+ mSiteMapManager = mapManager;
+ mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
+ mImm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
+ mPackageManager = context.getPackageManager();
+ }
+
+ @Override
+ protected void onDiscardResult(Set extends SearchResult> result) {
+ }
+
+ @Override
+ public Set extends SearchResult> loadInBackground() {
+ final Set results = new HashSet<>();
+ results.addAll(buildPhysicalKeyboardSearchResults());
+ results.addAll(buildVirtualKeyboardSearchResults());
+ return results;
+ }
+
+ private Set buildPhysicalKeyboardSearchResults() {
+ final Set results = new HashSet<>();
+ final Context context = getContext();
+ final String screenTitle = context.getString(R.string.physical_keyboard_title);
+
+ for (final InputDevice device : getPhysicalFullKeyboards()) {
+ final String deviceName = device.getName();
+ final int wordDiff = InstalledAppResultLoader.getWordDifference(deviceName, mQuery);
+ if (wordDiff == NAME_NO_MATCH) {
+ continue;
+ }
+ final String keyboardLayoutDescriptor = mInputManager
+ .getCurrentKeyboardLayoutForInputDevice(device.getIdentifier());
+ final KeyboardLayout keyboardLayout = (keyboardLayoutDescriptor != null)
+ ? mInputManager.getKeyboardLayout(keyboardLayoutDescriptor) : null;
+ final String summary = (keyboardLayout != null)
+ ? keyboardLayout.toString()
+ : context.getString(R.string.keyboard_layout_default_label);
+ final String key = deviceName;
+
+ final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context,
+ PHYSICAL_KEYBOARD_FRAGMENT, key, screenTitle);
+ results.add(new SearchResult.Builder()
+ .setTitle(deviceName)
+ .setPayload(new ResultPayload(intent))
+ .setStableId(Objects.hash(PHYSICAL_KEYBOARD_FRAGMENT, key))
+ .setSummary(summary)
+ .setRank(wordDiff)
+ .addBreadcrumbs(getPhysicalKeyboardBreadCrumb())
+ .build());
+ }
+ return results;
+ }
+
+ private Set buildVirtualKeyboardSearchResults() {
+ final Set results = new HashSet<>();
+ final Context context = getContext();
+ final String screenTitle = context.getString(R.string.add_virtual_keyboard);
+ final List inputMethods = mImm.getInputMethodList();
+ for (InputMethodInfo info : inputMethods) {
+ final String title = info.loadLabel(mPackageManager).toString();
+ final String summary = InputMethodAndSubtypeUtil
+ .getSubtypeLocaleNameListAsSentence(getAllSubtypesOf(info), context, info);
+ int wordDiff = InstalledAppResultLoader.getWordDifference(title, mQuery);
+ if (wordDiff == NAME_NO_MATCH) {
+ wordDiff = InstalledAppResultLoader.getWordDifference(summary, mQuery);
+ }
+ if (wordDiff == NAME_NO_MATCH) {
+ continue;
+ }
+ final ServiceInfo serviceInfo = info.getServiceInfo();
+ final String key = new ComponentName(serviceInfo.packageName, serviceInfo.name)
+ .flattenToString();
+ final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context,
+ VIRTUAL_KEYBOARD_FRAGMENT, key, screenTitle);
+ results.add(new SearchResult.Builder()
+ .setTitle(title)
+ .setSummary(summary)
+ .setRank(wordDiff)
+ .setStableId(Objects.hash(VIRTUAL_KEYBOARD_FRAGMENT, key))
+ .addBreadcrumbs(getVirtualKeyboardBreadCrumb())
+ .setPayload(new ResultPayload(intent))
+ .build());
+ }
+ return results;
+ }
+
+ private List getPhysicalKeyboardBreadCrumb() {
+ if (mPhysicalKeyboardBreadcrumb == null || mPhysicalKeyboardBreadcrumb.isEmpty()) {
+ final Context context = getContext();
+ mPhysicalKeyboardBreadcrumb = mSiteMapManager.buildBreadCrumb(
+ context, PHYSICAL_KEYBOARD_FRAGMENT,
+ context.getString(R.string.physical_keyboard_title));
+ }
+ return mPhysicalKeyboardBreadcrumb;
+ }
+
+
+ private List getVirtualKeyboardBreadCrumb() {
+ if (mVirtualKeyboardBreadcrumb == null || mVirtualKeyboardBreadcrumb.isEmpty()) {
+ final Context context = getContext();
+ mVirtualKeyboardBreadcrumb = mSiteMapManager.buildBreadCrumb(
+ context, VIRTUAL_KEYBOARD_FRAGMENT,
+ context.getString(R.string.add_virtual_keyboard));
+ }
+ return mVirtualKeyboardBreadcrumb;
+ }
+
+ private List getPhysicalFullKeyboards() {
+ final List keyboards = new ArrayList<>();
+ final int[] deviceIds = InputDevice.getDeviceIds();
+ if (deviceIds != null) {
+ for (int deviceId : deviceIds) {
+ final InputDevice device = InputDevice.getDevice(deviceId);
+ if (device != null && !device.isVirtual() && device.isFullKeyboard()) {
+ keyboards.add(device);
+ }
+ }
+ }
+ return keyboards;
+ }
+
+ private static List getAllSubtypesOf(final InputMethodInfo imi) {
+ final int subtypeCount = imi.getSubtypeCount();
+ final List allSubtypes = new ArrayList<>(subtypeCount);
+ for (int index = 0; index < subtypeCount; index++) {
+ allSubtypes.add(imi.getSubtypeAt(index));
+ }
+ return allSubtypes;
+ }
+}
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 7e0e08617ba..900cefc3a53 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -48,6 +48,11 @@ public interface SearchFeatureProvider {
AccessibilityServiceResultLoader getAccessibilityServiceResultLoader(Context context,
String query);
+ /**
+ * Returns a new loader to search input devices.
+ */
+ InputDeviceResultLoader getInputDeviceResultLoader(Context context, String query);
+
/**
* Returns a new loader to get all recently saved queries search terms.
*/
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index b90547e5a3b..400cf8fe5f3 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -61,6 +61,11 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider {
getSiteMapManager());
}
+ @Override
+ public InputDeviceResultLoader getInputDeviceResultLoader(Context context, String query) {
+ return new InputDeviceResultLoader(context, cleanQuery(query), getSiteMapManager());
+ }
+
@Override
public SavedQueryLoader getSavedQueryLoader(Context context) {
return new SavedQueryLoader(context);
diff --git a/src/com/android/settings/search/SearchFragment.java b/src/com/android/settings/search/SearchFragment.java
index fb89d6e5362..ccc4d61ff73 100644
--- a/src/com/android/settings/search/SearchFragment.java
+++ b/src/com/android/settings/search/SearchFragment.java
@@ -84,8 +84,10 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
static final int LOADER_ID_INSTALLED_APPS = 2;
@VisibleForTesting
static final int LOADER_ID_ACCESSIBILITY_SERVICES = 3;
+ @VisibleForTesting
+ static final int LOADER_ID_INPUT_DEVICES = 4;
- private static final int NUM_QUERY_LOADERS = 3;
+ private static final int NUM_QUERY_LOADERS = 4;
@VisibleForTesting
AtomicInteger mUnfinishedLoadersCount = new AtomicInteger(NUM_QUERY_LOADERS);
@@ -284,6 +286,7 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
loaderManager.destroyLoader(LOADER_ID_DATABASE);
loaderManager.destroyLoader(LOADER_ID_INSTALLED_APPS);
loaderManager.destroyLoader(LOADER_ID_ACCESSIBILITY_SERVICES);
+ loaderManager.destroyLoader(LOADER_ID_INPUT_DEVICES);
mShowingSavedQuery = true;
mSavedQueryController.loadSavedQueries();
mSearchFeatureProvider.hideFeedbackButton();
@@ -314,6 +317,8 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
return mSearchFeatureProvider.getInstalledAppSearchLoader(activity, mQuery);
case LOADER_ID_ACCESSIBILITY_SERVICES:
return mSearchFeatureProvider.getAccessibilityServiceResultLoader(activity, mQuery);
+ case LOADER_ID_INPUT_DEVICES:
+ return mSearchFeatureProvider.getInputDeviceResultLoader(activity, mQuery);
default:
return null;
}
@@ -351,6 +356,8 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
LOADER_ID_INSTALLED_APPS, null /* args */, this /* callback */);
loaderManager.initLoader(
LOADER_ID_ACCESSIBILITY_SERVICES, null /* args */, this /* callback */);
+ loaderManager.initLoader(
+ LOADER_ID_INPUT_DEVICES, null /* args */, this /* callback */);
}
requery();
@@ -392,6 +399,8 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
loaderManager.restartLoader(LOADER_ID_INSTALLED_APPS, null /* args */, this /* callback */);
loaderManager.restartLoader(LOADER_ID_ACCESSIBILITY_SERVICES, null /* args */,
this /* callback */);
+ loaderManager.restartLoader(LOADER_ID_INPUT_DEVICES, null /* args */,
+ this /* callback */);
}
public String getQuery() {
diff --git a/src/com/android/settings/search/SearchResultsAdapter.java b/src/com/android/settings/search/SearchResultsAdapter.java
index 6c58a0d039a..7b886a46cd0 100644
--- a/src/com/android/settings/search/SearchResultsAdapter.java
+++ b/src/com/android/settings/search/SearchResultsAdapter.java
@@ -57,7 +57,9 @@ public class SearchResultsAdapter extends RecyclerView.Adapter
@VisibleForTesting
static final String APP_RESULTS_LOADER_KEY = InstalledAppResultLoader.class.getName();
@VisibleForTesting
- static final String ACCESSIBLITY_LOADER_KEY = AccessibilityServiceResultLoader.class.getName();
+ static final String ACCESSIBILITY_LOADER_KEY = AccessibilityServiceResultLoader.class.getName();
+ @VisibleForTesting
+ static final String INPUT_DEVICE_LOADER_KEY = InputDeviceResultLoader.class.getName();
@VisibleForTesting
static final int MSG_RANKING_TIMED_OUT = 1;
@@ -265,17 +267,21 @@ public class SearchResultsAdapter extends RecyclerView.Adapter
List extends SearchResult> installedAppResults =
getSortedLoadedResults(APP_RESULTS_LOADER_KEY);
List extends SearchResult> accessibilityResults =
- getSortedLoadedResults(ACCESSIBLITY_LOADER_KEY);
+ getSortedLoadedResults(ACCESSIBILITY_LOADER_KEY);
+ List extends SearchResult> inputDeviceResults =
+ getSortedLoadedResults(INPUT_DEVICE_LOADER_KEY);
int dbSize = databaseResults.size();
int appSize = installedAppResults.size();
int a11ySize = accessibilityResults.size();
-
+ int inputDeviceSize = inputDeviceResults.size();
int dbIndex = 0;
int appIndex = 0;
int a11yIndex = 0;
+ int inputDeviceIndex = 0;
int rank = SearchResult.TOP_RANK;
+ // TODO: We need a helper method to do k-way merge.
mStaticallyRankedSearchResults.clear();
while (rank <= SearchResult.BOTTOM_RANK) {
while ((dbIndex < dbSize) && (databaseResults.get(dbIndex).rank == rank)) {
@@ -287,6 +293,10 @@ public class SearchResultsAdapter extends RecyclerView.Adapter
while ((a11yIndex < a11ySize) && (accessibilityResults.get(a11yIndex).rank == rank)) {
mStaticallyRankedSearchResults.add(accessibilityResults.get(a11yIndex++));
}
+ while (inputDeviceIndex < inputDeviceSize
+ && inputDeviceResults.get(inputDeviceIndex).rank == rank) {
+ mStaticallyRankedSearchResults.add(inputDeviceResults.get(inputDeviceIndex++));
+ }
rank++;
}
@@ -299,6 +309,9 @@ public class SearchResultsAdapter extends RecyclerView.Adapter
while(a11yIndex < a11ySize) {
mStaticallyRankedSearchResults.add(accessibilityResults.get(a11yIndex++));
}
+ while (inputDeviceIndex < inputDeviceSize) {
+ mStaticallyRankedSearchResults.add(inputDeviceResults.get(inputDeviceIndex++));
+ }
}
private void updateSearchResults() {
@@ -332,12 +345,16 @@ public class SearchResultsAdapter extends RecyclerView.Adapter
List extends SearchResult> installedAppResults =
getSortedLoadedResults(APP_RESULTS_LOADER_KEY);
List extends SearchResult> accessibilityResults =
- getSortedLoadedResults(ACCESSIBLITY_LOADER_KEY);
+ getSortedLoadedResults(ACCESSIBILITY_LOADER_KEY);
+ List extends SearchResult> inputDeviceResults =
+ getSortedLoadedResults(INPUT_DEVICE_LOADER_KEY);
int dbSize = databaseResults.size();
int appSize = installedAppResults.size();
int a11ySize = accessibilityResults.size();
+ int inputDeviceSize = inputDeviceResults.size();
- final List asyncRankingResults = new ArrayList<>(dbSize + appSize + a11ySize);
+ final List asyncRankingResults = new ArrayList<>(
+ dbSize + appSize + a11ySize + inputDeviceSize);
TreeSet dbResultsSortedByScores = new TreeSet<>(
new Comparator() {
@Override
@@ -358,13 +375,13 @@ public class SearchResultsAdapter extends RecyclerView.Adapter
// Other results are not ranked by async ranking and appended at the end of the list.
asyncRankingResults.addAll(installedAppResults);
asyncRankingResults.addAll(accessibilityResults);
+ asyncRankingResults.addAll(inputDeviceResults);
return asyncRankingResults;
}
@VisibleForTesting
Set extends SearchResult> getUnsortedLoadedResults(String loaderKey) {
- return mResultsMap.containsKey(loaderKey) ?
- mResultsMap.get(loaderKey) : new HashSet();
+ return mResultsMap.containsKey(loaderKey) ? mResultsMap.get(loaderKey) : new HashSet<>();
}
@VisibleForTesting
diff --git a/tests/robotests/src/com/android/settings/SetupChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/SetupChooseLockPatternTest.java
index 78bc7d14768..69a13517951 100644
--- a/tests/robotests/src/com/android/settings/SetupChooseLockPatternTest.java
+++ b/tests/robotests/src/com/android/settings/SetupChooseLockPatternTest.java
@@ -30,7 +30,6 @@ import com.android.settings.password.ChooseLockPattern.IntentBuilder;
import com.android.settings.password.SetupChooseLockPattern;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.testutils.shadow.ShadowUtils;
@@ -49,7 +48,6 @@ import org.robolectric.res.builder.RobolectricPackageManager.ComponentState;
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class,
ShadowUtils.class
})
diff --git a/tests/robotests/src/com/android/settings/applications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/ManageApplicationsTest.java
index 92aa675c00d..8ed72848457 100644
--- a/tests/robotests/src/com/android/settings/applications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/ManageApplicationsTest.java
@@ -16,6 +16,17 @@
package com.android.settings.applications;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -35,7 +46,6 @@ import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.SettingsShadowResources.SettingsShadowTheme;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.widget.LoadingViewController;
import com.android.settingslib.applications.ApplicationsState;
@@ -53,17 +63,6 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* Tests for {@link ManageApplications}.
*/
@@ -74,7 +73,6 @@ import static org.mockito.Mockito.when;
shadows = {
SettingsShadowResources.class,
SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class
})
public class ManageApplicationsTest {
diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
index 8a8a13d02be..6b56c291324 100644
--- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
+++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java
@@ -15,6 +15,19 @@
*/
package com.android.settings.dashboard;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -38,7 +51,6 @@ import com.android.settings.dashboard.suggestions.SuggestionAdapter;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
@@ -56,26 +68,12 @@ import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION,
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class
})
public class DashboardAdapterTest {
diff --git a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
index 344914a4941..ad52bf6026e 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/FingerprintEnrollFindSensorTest.java
@@ -36,7 +36,6 @@ import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.IFingerprintManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.testutils.shadow.ShadowUtils;
@@ -61,7 +60,6 @@ import org.robolectric.shadows.ShadowActivity.IntentForResult;
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class,
ShadowUtils.class
})
diff --git a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
index f1b7ee0a231..3b678519064 100644
--- a/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
+++ b/tests/robotests/src/com/android/settings/fingerprint/SetupFingerprintEnrollFindSensorTest.java
@@ -30,7 +30,6 @@ import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.password.IFingerprintManager;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.testutils.shadow.ShadowUtils;
@@ -53,7 +52,6 @@ import org.robolectric.shadows.ShadowAlertDialog;
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class,
ShadowUtils.class
})
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
index 013d379b8b1..e434bb327fd 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryHeaderPreferenceControllerTest.java
@@ -17,6 +17,15 @@
package com.android.settings.fuelgauge;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -27,11 +36,10 @@ import android.support.v7.widget.RecyclerView;
import android.widget.TextView;
import com.android.settings.R;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.applications.LayoutPreference;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -45,23 +53,12 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION,
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEntityHeaderController.class
})
public class BatteryHeaderPreferenceControllerTest {
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java
index e3a94d24a42..3a1fad0fcbf 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryMeterViewTest.java
@@ -16,15 +16,17 @@
package com.android.settings.fuelgauge;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import android.content.Context;
import android.graphics.ColorFilter;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.SettingsShadowResources.SettingsShadowTheme;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import org.junit.Before;
import org.junit.Test;
@@ -34,10 +36,6 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
@RunWith(SettingsRobolectricTestRunner.class)
// TODO: Consider making the shadow class set global using a robolectric.properties file.
@Config(manifest = TestConfig.MANIFEST_PATH,
@@ -45,7 +43,6 @@ import static org.mockito.Mockito.verify;
shadows = {
SettingsShadowResources.class,
SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class
})
public class BatteryMeterViewTest {
private static final int BATTERY_LEVEL = 100;
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 83e630dfa79..48a48b1abce 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -18,9 +18,7 @@ package com.android.settings.fuelgauge;
import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_ADDITIONAL_BATTERY_INFO;
import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_HIGH_POWER_APPS;
import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_TOGGLE_APPS;
-
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
@@ -34,8 +32,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import java.util.List;
-
import android.app.LoaderManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -68,7 +64,6 @@ import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settingslib.core.AbstractPreferenceController;
import org.junit.Before;
@@ -95,7 +90,6 @@ import java.util.List;
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class
})
public class PowerUsageSummaryTest {
private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"};
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
index 5fa731eddc1..b8f06793ac3 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPasswordTest.java
@@ -31,7 +31,6 @@ import com.android.settings.password.ChooseLockPassword.ChooseLockPasswordFragme
import com.android.settings.password.ChooseLockPassword.IntentBuilder;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.setupwizardlib.GlifLayout;
@@ -52,7 +51,6 @@ import org.robolectric.shadows.ShadowDrawable;
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class,
ShadowUtils.class
})
diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
index b2380496ae1..c74448b5dd9 100644
--- a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
+++ b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java
@@ -29,7 +29,6 @@ import com.android.settings.password.ChooseLockPattern.ChooseLockPatternFragment
import com.android.settings.password.ChooseLockPattern.IntentBuilder;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.setupwizardlib.GlifLayout;
@@ -48,7 +47,6 @@ import org.robolectric.shadows.ShadowDrawable;
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class,
ShadowUtils.class
})
diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java
index 39a0fb66663..1195a2c2ecd 100644
--- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java
@@ -34,7 +34,6 @@ import com.android.settings.password.ChooseLockPassword.IntentBuilder;
import com.android.settings.password.SetupChooseLockPassword.SetupChooseLockPasswordFragment;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.testutils.shadow.ShadowUtils;
@@ -62,7 +61,6 @@ import java.util.List;
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class,
ShadowUtils.class
})
diff --git a/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java b/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java
index 639349dafd9..0e6f28a5686 100644
--- a/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java
+++ b/tests/robotests/src/com/android/settings/password/SetupSkipDialogTest.java
@@ -27,7 +27,6 @@ import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.ShadowDynamicIndexableContentMonitor;
import com.android.settings.testutils.shadow.ShadowEventLogWriter;
import com.android.settings.testutils.shadow.ShadowUtils;
@@ -40,13 +39,11 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowAlertDialog;
@RunWith(SettingsRobolectricTestRunner.class)
-@Config(
- manifest = TestConfig.MANIFEST_PATH,
+@Config(manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION,
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
- ShadowDynamicIndexableContentMonitor.class,
ShadowEventLogWriter.class,
ShadowUtils.class
})
diff --git a/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java b/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java
deleted file mode 100644
index 26c89d5e9b8..00000000000
--- a/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- * 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.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.Settings;
-import android.provider.UserDictionary;
-import android.view.inputmethod.InputMethodInfo;
-
-import com.android.internal.content.PackageMonitor;
-import com.android.settings.TestConfig;
-import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
-import com.android.settings.inputmethod.PhysicalKeyboardFragment;
-import com.android.settings.inputmethod.VirtualKeyboardFragment;
-import com.android.settings.language.LanguageAndInputSettings;
-import com.android.settings.print.PrintSettingsFragment;
-import com.android.settings.testutils.DatabaseTestUtils;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
-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.Mock;
-import org.mockito.MockitoAnnotations;
-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 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";
-
- @Mock
- private LoaderManager mLoaderManager;
- @Mock
- private DatabaseIndexingManager mIndexManager;
-
- 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() {
- MockitoAnnotations.initMocks(this);
- 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() {
- mMonitor.unregister(mActivity, LOADER_ID);
- // BroadcastReceiver must be unregistered.
- assertThat(extractPackageMonitor()).isNull();
-
- DynamicIndexableContentMonitor.resetForTesting();
- mRobolectricPackageManager.reset();
-
- DatabaseTestUtils.clearDb(mActivity);
- }
-
- @Test
- public void testLockedUser() {
- mMonitor.register(mActivity, LOADER_ID, mIndexManager, false /* isUserUnlocked */);
-
- // No loader procedure happens.
- verify(mLoaderManager, never()).initLoader(
- anyInt(), any(Bundle.class), any(LoaderManager.LoaderCallbacks.class));
- // No indexing happens.
- verify(mIndexManager, never()).updateFromClassNameResource(
- anyString(), 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, mIndexManager, 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());
- // BroadcastReceiver must be unregistered.
- assertThat(extractPackageMonitor()).isNull();
-
- // To suppress spurious test fail in {@link #shutDown()}.
- mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);
- }
-
- @Test
- public void testPrinterServiceIndex() {
- mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);
-
- // Loader procedure happens.
- verify(mLoaderManager, only()).initLoader(LOADER_ID, null, mMonitor);
-
- // Loading print services happens.
- final Loader> 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, mIndexManager, true /* isUserUnlocked */);
-
- // Rebuild indexing should happen.
- verifyIncrementalIndexing(PhysicalKeyboardFragment.class);
- // Input monitor should be registered to InputManager.
- final InputManager.InputDeviceListener listener = extactInputDeviceListener();
- assertThat(listener).isNotNull();
-
- /*
- * Nothing happens on successive register calls.
- */
- mMonitor.unregister(mActivity, LOADER_ID);
- reset(mIndexManager);
-
- mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);
-
- verifyNoIndexing(PhysicalKeyboardFragment.class);
- assertThat(extactInputDeviceListener()).isEqualTo(listener);
-
- /*
- * A device is added.
- */
- reset(mIndexManager);
-
- listener.onInputDeviceAdded(1 /* deviceId */);
-
- verifyIncrementalIndexing(PhysicalKeyboardFragment.class);
-
- /*
- * A device is removed.
- */
- reset(mIndexManager);
-
- listener.onInputDeviceRemoved(2 /* deviceId */);
-
- verifyIncrementalIndexing(PhysicalKeyboardFragment.class);
-
- /*
- * A device is changed.
- */
- reset(mIndexManager);
-
- listener.onInputDeviceChanged(3 /* deviceId */);
-
- verifyIncrementalIndexing(PhysicalKeyboardFragment.class);
- }
-
- @Test
- public void testInputMethodServicesMonitor() throws Exception {
- mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);
-
- verifyIncrementalIndexing(VirtualKeyboardFragment.class);
- verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
-
- final Uri enabledInputMethodsContentUri = Settings.Secure.getUriFor(
- Settings.Secure.ENABLED_INPUT_METHODS);
- // Content observer should be registered.
- final ContentObserver observer = extractContentObserver(enabledInputMethodsContentUri);
- assertThat(observer).isNotNull();
-
- /*
- * When an input method service package is installed, incremental indexing happen.
- */
- reset(mIndexManager);
-
- installInputMethodService(IME_PACKAGE_1);
-
- verifyIncrementalIndexing(VirtualKeyboardFragment.class);
- verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
-
- /*
- * When another input method service package is installed, incremental indexing happens.
- */
- reset(mIndexManager);
-
- installInputMethodService(IME_PACKAGE_2);
-
- verifyIncrementalIndexing(VirtualKeyboardFragment.class);
- verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
-
- /*
- * When an input method service is disabled, rebuild indexing happens.
- */
- reset(mIndexManager);
-
- disableInstalledPackage(IME_PACKAGE_1);
-
- verifyIncrementalIndexing(VirtualKeyboardFragment.class);
- verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
-
- /*
- * When an input method service is enabled, incremental indexing happens.
- */
- reset(mIndexManager);
-
- enableInstalledPackage(IME_PACKAGE_1);
-
- verifyIncrementalIndexing(VirtualKeyboardFragment.class);
- verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
-
- /*
- * When an input method service package is uninstalled, rebuild indexing happens.
- */
- reset(mIndexManager);
-
- uninstallInputMethodService(IME_PACKAGE_1);
-
- verifyIncrementalIndexing(VirtualKeyboardFragment.class);
- verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
-
- /*
- * When an accessibility service package is installed, nothing happens.
- */
- reset(mIndexManager);
-
- installAccessibilityService(A11Y_PACKAGE_1);
-
- verifyNoIndexing(VirtualKeyboardFragment.class);
- verifyNoIndexing(AvailableVirtualKeyboardFragment.class);
-
- /*
- * When enabled IMEs list is changed, rebuild indexing happens.
- */
- reset(mIndexManager);
-
- observer.onChange(false /* selfChange */, enabledInputMethodsContentUri);
-
- verifyIncrementalIndexing(VirtualKeyboardFragment.class);
- verifyIncrementalIndexing(AvailableVirtualKeyboardFragment.class);
- }
-
- @Test
- public void testUserDictionaryChangeMonitor() throws Exception {
- mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */);
-
- // Content observer should be registered.
- final ContentObserver observer = extractContentObserver(UserDictionary.Words.CONTENT_URI);
- assertThat(observer).isNotNull();
-
- verifyIncrementalIndexing(LanguageAndInputSettings.class);
-
- /*
- * When user dictionary content is changed, rebuild indexing happens.
- */
- reset(mIndexManager);
-
- observer.onChange(false /* selfChange */, UserDictionary.Words.CONTENT_URI);
-
- verifyIncrementalIndexing(LanguageAndInputSettings.class);
- }
-
- /*
- * Verification helpers.
- */
-
- private void verifyNoIndexing(Class> indexingClass) {
- verify(mIndexManager, never()).updateFromClassNameResource(eq(indexingClass.getName()),
- anyBoolean());
- }
-
- private void verifyIncrementalIndexing(Class> indexingClass) {
- verify(mIndexManager, times(1)).updateFromClassNameResource(indexingClass.getName(),
- true /* includeInSearchResults */);
- verify(mIndexManager, never()).updateFromClassNameResource(indexingClass.getName(),
- false /* includeInSearchResults */);
- }
-
- /*
- * Testing helper methods.
- */
-
- private InputManager.InputDeviceListener extactInputDeviceListener() {
- List 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 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 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 enableInstalledPackage(String packageName) {
- ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
- packageName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0 /* flags */);
- extractPackageMonitor().onPackageModified(packageName);
- Robolectric.flushBackgroundThreadScheduler();
- }
-
- private void disableInstalledPackage(String packageName) {
- ((PackageManager) mRobolectricPackageManager).setApplicationEnabledSetting(
- packageName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0 /* flags */);
- extractPackageMonitor().onPackageModified(packageName);
- Robolectric.flushBackgroundThreadScheduler();
- }
-
- private void installAccessibilityService(String packageName) throws Exception {
- final AccessibilityServiceInfo serviceToAdd = buildAccessibilityServiceInfo(packageName);
-
- final List 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);
-
- extractPackageMonitor()
- .onPackageAppeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
- Robolectric.flushBackgroundThreadScheduler();
- }
-
- private void uninstallAccessibilityService(String packageName) throws Exception {
- final AccessibilityServiceInfo serviceToRemove = buildAccessibilityServiceInfo(packageName);
-
- final List 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);
-
- extractPackageMonitor()
- .onPackageDisappeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
- Robolectric.flushBackgroundThreadScheduler();
- }
-
- private void installInputMethodService(String packageName) throws Exception {
- final ResolveInfo resolveInfoToAdd = buildResolveInfo(packageName, "imeService");
- final InputMethodInfo serviceToAdd = buildInputMethodInfo(resolveInfoToAdd);
-
- final List 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);
-
- extractPackageMonitor()
- .onPackageAppeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
- Robolectric.flushBackgroundThreadScheduler();
- }
-
- private void uninstallInputMethodService(String packageName) throws Exception {
- final ResolveInfo resolveInfoToRemove = buildResolveInfo(packageName, "imeService");
- final InputMethodInfo serviceToRemove = buildInputMethodInfo(resolveInfoToRemove);
-
- final List 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);
-
- extractPackageMonitor()
- .onPackageDisappeared(packageName, PackageMonitor.PACKAGE_PERMANENT_CHANGE);
- Robolectric.flushBackgroundThreadScheduler();
- }
-
- 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/search/InputDeviceResultLoaderTest.java b/tests/robotests/src/com/android/settings/search/InputDeviceResultLoaderTest.java
new file mode 100644
index 00000000000..a955af179ff
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/search/InputDeviceResultLoaderTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2017 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 android.content.Context.INPUT_METHOD_SERVICE;
+import static com.android.settings.search.InputDeviceResultLoader.PHYSICAL_KEYBOARD_FRAGMENT;
+import static com.android.settings.search.InputDeviceResultLoader.VIRTUAL_KEYBOARD_FRAGMENT;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.hardware.input.InputManager;
+import android.view.InputDevice;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.dashboard.SiteMapManager;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowInputDevice;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH,
+ sdk = TestConfig.SDK_VERSION,
+ shadows = {
+ ShadowInputDevice.class
+ })
+public class InputDeviceResultLoaderTest {
+
+ private static final String QUERY = "test_query";
+ private static final List PHYSICAL_KEYBOARD_BREADCRUMB;
+ private static final List VIRTUAL_KEYBOARD_BREADCRUMB;
+
+ static {
+ PHYSICAL_KEYBOARD_BREADCRUMB = new ArrayList<>();
+ VIRTUAL_KEYBOARD_BREADCRUMB = new ArrayList<>();
+ PHYSICAL_KEYBOARD_BREADCRUMB.add("Settings");
+ PHYSICAL_KEYBOARD_BREADCRUMB.add("physical keyboard");
+ VIRTUAL_KEYBOARD_BREADCRUMB.add("Settings");
+ VIRTUAL_KEYBOARD_BREADCRUMB.add("virtual keyboard");
+ }
+
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private Context mContext;
+ @Mock
+ private SiteMapManager mSiteMapManager;
+ @Mock
+ private InputManager mInputManager;
+ @Mock
+ private InputMethodManager mImm;
+ @Mock
+ private PackageManager mPackageManager;
+
+ private InputDeviceResultLoader mLoader;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ when(mContext.getApplicationContext()).thenReturn(mContext);
+ when(mContext.getSystemService(Context.INPUT_SERVICE))
+ .thenReturn(mInputManager);
+ when(mContext.getSystemService(INPUT_METHOD_SERVICE))
+ .thenReturn(mImm);
+ when(mContext.getPackageManager())
+ .thenReturn(mPackageManager);
+ when(mContext.getString(anyInt()))
+ .thenAnswer(invocation -> RuntimeEnvironment.application.getString(
+ (Integer) invocation.getArguments()[0]));
+ mLoader = new InputDeviceResultLoader(mContext, QUERY, mSiteMapManager);
+ }
+
+ @After
+ public void tearDown() {
+ ShadowInputDevice.reset();
+ }
+
+ @Test
+ public void query_noKeyboard_shouldNotReturnAnything() {
+ assertThat(mLoader.loadInBackground()).isEmpty();
+ }
+
+ @Test
+ public void query_hasPhysicalKeyboard_match() {
+ addPhysicalKeyboard(QUERY);
+ when(mSiteMapManager.buildBreadCrumb(mContext, PHYSICAL_KEYBOARD_FRAGMENT,
+ RuntimeEnvironment.application.getString(R.string.physical_keyboard_title)))
+ .thenReturn(PHYSICAL_KEYBOARD_BREADCRUMB);
+
+ final List results = new ArrayList<>(mLoader.loadInBackground());
+
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).title).isEqualTo(QUERY);
+ assertThat(results.get(0).breadcrumbs)
+ .containsExactlyElementsIn(PHYSICAL_KEYBOARD_BREADCRUMB);
+ }
+
+ @Test
+ public void query_hasVirtualKeyboard_match() {
+ addVirtualKeyboard(QUERY);
+ when(mSiteMapManager.buildBreadCrumb(mContext, VIRTUAL_KEYBOARD_FRAGMENT,
+ RuntimeEnvironment.application.getString(R.string.add_virtual_keyboard)))
+ .thenReturn(VIRTUAL_KEYBOARD_BREADCRUMB);
+
+ final List results = new ArrayList<>(mLoader.loadInBackground());
+ assertThat(results).hasSize(1);
+ assertThat(results.get(0).title).isEqualTo(QUERY);
+ assertThat(results.get(0).breadcrumbs)
+ .containsExactlyElementsIn(VIRTUAL_KEYBOARD_BREADCRUMB);
+ }
+
+ @Test
+ public void query_hasPhysicalVirtualKeyboard_doNotMatch() {
+ addPhysicalKeyboard("abc");
+ addVirtualKeyboard("def");
+
+ assertThat(mLoader.loadInBackground()).isEmpty();
+ verifyZeroInteractions(mSiteMapManager);
+ }
+
+ private void addPhysicalKeyboard(String name) {
+ final InputDevice device = mock(InputDevice.class);
+ when(device.isVirtual()).thenReturn(false);
+ when(device.isFullKeyboard()).thenReturn(true);
+ when(device.getName()).thenReturn(name);
+ ShadowInputDevice.sDeviceIds = new int[]{0};
+ ShadowInputDevice.addDevice(0, device);
+ }
+
+ private void addVirtualKeyboard(String name) {
+ final List imis = new ArrayList<>();
+ final InputMethodInfo info = mock(InputMethodInfo.class);
+ imis.add(info);
+ when(info.getServiceInfo()).thenReturn(new ServiceInfo());
+ when(info.loadLabel(mPackageManager)).thenReturn(name);
+ info.getServiceInfo().packageName = "pkg";
+ info.getServiceInfo().name = "class";
+ when(mImm.getInputMethodList()).thenReturn(imis);
+ }
+
+}
diff --git a/tests/robotests/src/com/android/settings/search/MockAccessibilityLoader.java b/tests/robotests/src/com/android/settings/search/MockAccessibilityLoader.java
new file mode 100644
index 00000000000..0a06a351915
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/search/MockAccessibilityLoader.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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 android.content.Context;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class MockAccessibilityLoader extends AccessibilityServiceResultLoader {
+
+ public MockAccessibilityLoader(Context context) {
+ super(context, "test_query", null);
+ }
+
+ @Override
+ public Set extends SearchResult> loadInBackground() {
+ return new HashSet<>();
+ }
+
+ @Override
+ protected void onDiscardResult(Set extends SearchResult> result) {
+
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/search/MockAccessiblityLoader.java b/tests/robotests/src/com/android/settings/search/MockInputDeviceResultLoader.java
similarity index 88%
rename from tests/robotests/src/com/android/settings/search/MockAccessiblityLoader.java
rename to tests/robotests/src/com/android/settings/search/MockInputDeviceResultLoader.java
index aa9b778e299..2c16b14a3b0 100644
--- a/tests/robotests/src/com/android/settings/search/MockAccessiblityLoader.java
+++ b/tests/robotests/src/com/android/settings/search/MockInputDeviceResultLoader.java
@@ -21,9 +21,8 @@ import android.content.Context;
import java.util.HashSet;
import java.util.Set;
-public class MockAccessiblityLoader extends AccessibilityServiceResultLoader {
-
- public MockAccessiblityLoader(Context context) {
+public class MockInputDeviceResultLoader extends InputDeviceResultLoader {
+ public MockInputDeviceResultLoader(Context context) {
super(context, "test_query", null);
}
diff --git a/tests/robotests/src/com/android/settings/search/SearchFragmentTest.java b/tests/robotests/src/com/android/settings/search/SearchFragmentTest.java
index 658880528ab..71c31aa149b 100644
--- a/tests/robotests/src/com/android/settings/search/SearchFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchFragmentTest.java
@@ -17,6 +17,20 @@
package com.android.settings.search;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
import android.app.LoaderManager;
import android.content.Context;
import android.content.Intent;
@@ -28,10 +42,10 @@ import android.view.View;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.DatabaseTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.After;
@@ -52,20 +66,6 @@ import org.robolectric.util.ReflectionHelpers;
import java.util.Set;
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION,
@@ -83,6 +83,8 @@ public class SearchFragmentTest {
private InstalledAppResultLoader mInstalledAppResultLoader;
@Mock
private AccessibilityServiceResultLoader mAccessibilityServiceResultLoader;
+ @Mock
+ private InputDeviceResultLoader mInputDeviceResultLoader;
@Mock
private SavedQueryLoader mSavedQueryLoader;
@@ -118,6 +120,9 @@ public class SearchFragmentTest {
when(mFeatureFactory.searchFeatureProvider
.getAccessibilityServiceResultLoader(any(Context.class), anyString()))
.thenReturn(mAccessibilityServiceResultLoader);
+ when(mFeatureFactory.searchFeatureProvider
+ .getInputDeviceResultLoader(any(Context.class), anyString()))
+ .thenReturn(mInputDeviceResultLoader);
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
.thenReturn(mSavedQueryLoader);
@@ -178,6 +183,9 @@ public class SearchFragmentTest {
when(mFeatureFactory.searchFeatureProvider
.getAccessibilityServiceResultLoader(any(Context.class), anyString()))
.thenReturn(mAccessibilityServiceResultLoader);
+ when(mFeatureFactory.searchFeatureProvider
+ .getInputDeviceResultLoader(any(Context.class), anyString()))
+ .thenReturn(mInputDeviceResultLoader);
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
.thenReturn(mSavedQueryLoader);
@@ -236,6 +244,9 @@ public class SearchFragmentTest {
when(mFeatureFactory.searchFeatureProvider
.getAccessibilityServiceResultLoader(any(Context.class), anyString()))
.thenReturn(mAccessibilityServiceResultLoader);
+ when(mFeatureFactory.searchFeatureProvider
+ .getInputDeviceResultLoader(any(Context.class), anyString()))
+ .thenReturn(mInputDeviceResultLoader);
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
.thenReturn(mSavedQueryLoader);
ActivityController activityController =
@@ -270,6 +281,9 @@ public class SearchFragmentTest {
when(mFeatureFactory.searchFeatureProvider
.getAccessibilityServiceResultLoader(any(Context.class), anyString()))
.thenReturn(mAccessibilityServiceResultLoader);
+ when(mFeatureFactory.searchFeatureProvider
+ .getInputDeviceResultLoader(any(Context.class), anyString()))
+ .thenReturn(mInputDeviceResultLoader);
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
.thenReturn(mSavedQueryLoader);
@@ -349,7 +363,10 @@ public class SearchFragmentTest {
.thenReturn(new MockAppLoader(RuntimeEnvironment.application));
when(mFeatureFactory.searchFeatureProvider
.getAccessibilityServiceResultLoader(any(Context.class), anyString()))
- .thenReturn(new MockAccessiblityLoader(RuntimeEnvironment.application));
+ .thenReturn(new MockAccessibilityLoader(RuntimeEnvironment.application));
+ when(mFeatureFactory.searchFeatureProvider
+ .getInputDeviceResultLoader(any(Context.class), anyString()))
+ .thenReturn(new MockInputDeviceResultLoader(RuntimeEnvironment.application));
when(mFeatureFactory.searchFeatureProvider.getSavedQueryLoader(any(Context.class)))
.thenReturn(mSavedQueryLoader);
ActivityController activityController =
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDynamicIndexableContentMonitor.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDynamicIndexableContentMonitor.java
deleted file mode 100644
index de5d243624f..00000000000
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDynamicIndexableContentMonitor.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.android.settings.testutils.shadow;
-
-import android.app.Activity;
-import android.os.UserManager;
-import com.android.settings.search.DynamicIndexableContentMonitor;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.annotation.RealObject;
-
-/**
- * A shadow class of {@link DynamicIndexableContentMonitor}. The real implementation of
- * {@link DynamicIndexableContentMonitor#register} calls {@link UserManager#isUserUnlocked()}, which
- * Robolectric has not yet been updated to support, so throws a NoSuchMethodError exception.
- */
-// TODO: Delete this once Robolectric is updated to the latest SDK.
-@Implements(DynamicIndexableContentMonitor.class)
-public class ShadowDynamicIndexableContentMonitor {
-
- @Implementation
- public void register(Activity activity, int loaderId) {
- }
-}