From 5c83cfa27805ac0f96d04ac99f0e8fbde20329ed Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Thu, 16 Mar 2017 13:33:18 -0700 Subject: [PATCH] Remove Index.java from old Search and its dependents Test: make RunSettingsRoboTests Bug: 35763944, 36192909 Change-Id: If216e1eeb4c29e7372720c6228fa4e99ea2a9904 --- res/values/strings.xml | 2 - res/xml/home_selection.xml | 23 - src/com/android/settings/HomeSettings.java | 430 ------ .../android/settings/SecuritySettings.java | 6 +- .../bluetooth/BluetoothDevicePreference.java | 13 - .../settings/bluetooth/BluetoothEnabler.java | 28 - .../bluetooth/DeviceProfilesSettings.java | 5 - src/com/android/settings/bluetooth/Utils.java | 17 - .../core/gateway/SettingsGateway.java | 2 - .../BuildNumberPreferenceController.java | 7 +- .../DynamicIndexableContentMonitor.java | 75 +- src/com/android/settings/search/Index.java | 1336 ----------------- .../search2/DatabaseIndexingManager.java | 3 + .../search2/SearchFeatureProviderImpl.java | 7 +- .../android/settings/wifi/WifiEnabler.java | 28 - .../BuildNumberPreferenceControllerTest.java | 6 +- .../DynamicIndexableContentMonitorTest.java | 76 +- .../search/SearchFeatureProviderImplTest.java | 9 - .../SearchIndexProviderCodeInspector.java | 12 +- 19 files changed, 104 insertions(+), 1981 deletions(-) delete mode 100644 res/xml/home_selection.xml delete mode 100644 src/com/android/settings/HomeSettings.java delete mode 100644 src/com/android/settings/search/Index.java diff --git a/res/values/strings.xml b/res/values/strings.xml index fc484b0b812..7ad1661ec11 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2068,8 +2068,6 @@ - - Home Display Sound diff --git a/res/xml/home_selection.xml b/res/xml/home_selection.xml deleted file mode 100644 index a348f9d3ffe..00000000000 --- a/res/xml/home_selection.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/src/com/android/settings/HomeSettings.java b/src/com/android/settings/HomeSettings.java deleted file mode 100644 index 9896d528e1a..00000000000 --- a/src/com/android/settings/HomeSettings.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (C) 2013 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; - -import android.app.Activity; -import android.app.ActivityManager; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.UserInfo; -import android.content.res.Resources; -import android.graphics.ColorFilter; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.UserManager; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceGroup; -import android.support.v7.preference.PreferenceViewHolder; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageView; -import android.widget.RadioButton; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Index; -import com.android.settings.search.Indexable; -import com.android.settings.search.SearchIndexableRaw; - -import java.util.ArrayList; -import java.util.List; - -public class HomeSettings extends SettingsPreferenceFragment implements Indexable { - static final String TAG = "HomeSettings"; - - // Boolean extra, indicates only launchers that support managed profiles should be shown. - // Note: must match the constant defined in ManagedProvisioning - private static final String EXTRA_SUPPORT_MANAGED_PROFILES = "support_managed_profiles"; - - static final int REQUESTING_UNINSTALL = 10; - - public static final String HOME_PREFS = "home_prefs"; - public static final String HOME_PREFS_DO_SHOW = "do_show"; - - public static final String HOME_SHOW_NOTICE = "show"; - - private class HomePackageReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - buildHomeActivitiesList(); - Index.getInstance(context).updateFromClassNameResource( - HomeSettings.class.getName(), true, true); - } - } - - private PreferenceGroup mPrefGroup; - private PackageManager mPm; - private ComponentName[] mHomeComponentSet; - private ArrayList mPrefs; - private HomeAppPreference mCurrentHome = null; - private final IntentFilter mHomeFilter; - private boolean mShowNotice; - private HomePackageReceiver mHomePackageReceiver = new HomePackageReceiver(); - - public HomeSettings() { - mHomeFilter = new IntentFilter(Intent.ACTION_MAIN); - mHomeFilter.addCategory(Intent.CATEGORY_HOME); - mHomeFilter.addCategory(Intent.CATEGORY_DEFAULT); - } - - OnClickListener mHomeClickListener = new OnClickListener() { - @Override - public void onClick(View v) { - int index = (Integer)v.getTag(); - HomeAppPreference pref = mPrefs.get(index); - if (!pref.isChecked) { - makeCurrentHome(pref); - } - } - }; - - OnClickListener mDeleteClickListener = new OnClickListener() { - @Override - public void onClick(View v) { - int index = (Integer)v.getTag(); - uninstallApp(mPrefs.get(index)); - } - }; - - void makeCurrentHome(HomeAppPreference newHome) { - if (mCurrentHome != null) { - mCurrentHome.setChecked(false); - } - newHome.setChecked(true); - mCurrentHome = newHome; - - mPm.replacePreferredActivity(mHomeFilter, IntentFilter.MATCH_CATEGORY_EMPTY, - mHomeComponentSet, newHome.activityName); - - getActivity().setResult(Activity.RESULT_OK); - } - - void uninstallApp(HomeAppPreference pref) { - // Uninstallation is done by asking the OS to do it - Uri packageURI = Uri.parse("package:" + pref.uninstallTarget); - Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, packageURI); - uninstallIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); - int requestCode = REQUESTING_UNINSTALL + (pref.isChecked ? 1 : 0); - startActivityForResult(uninstallIntent, requestCode); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - // Rebuild the list now that we might have nuked something - buildHomeActivitiesList(); - - // if the previous home app is now gone, fall back to the system one - if (requestCode > REQUESTING_UNINSTALL) { - // if mCurrentHome has gone null, it means we didn't find the previously- - // default home app when rebuilding the list, i.e. it was the one we - // just uninstalled. When that happens we make the system-bundled - // home app the active default. - if (mCurrentHome == null) { - for (int i = 0; i < mPrefs.size(); i++) { - HomeAppPreference pref = mPrefs.get(i); - if (pref.isSystem) { - makeCurrentHome(pref); - break; - } - } - } - } - } - - private void buildHomeActivitiesList() { - ArrayList homeActivities = new ArrayList(); - ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); - - Context context = getPrefContext(); - mCurrentHome = null; - mPrefGroup.removeAll(); - mPrefs = new ArrayList(); - mHomeComponentSet = new ComponentName[homeActivities.size()]; - int prefIndex = 0; - boolean supportManagedProfilesExtra = - getActivity().getIntent().getBooleanExtra(EXTRA_SUPPORT_MANAGED_PROFILES, false); - boolean mustSupportManagedProfile = hasManagedProfile() - || supportManagedProfilesExtra; - for (int i = 0; i < homeActivities.size(); i++) { - final ResolveInfo candidate = homeActivities.get(i); - final ActivityInfo info = candidate.activityInfo; - ComponentName activityName = new ComponentName(info.packageName, info.name); - mHomeComponentSet[i] = activityName; - try { - Drawable icon = info.loadIcon(mPm); - CharSequence name = info.loadLabel(mPm); - HomeAppPreference pref; - - if (mustSupportManagedProfile && !launcherHasManagedProfilesFeature(candidate)) { - pref = new HomeAppPreference(context, activityName, prefIndex, - icon, name, this, info, false /* not enabled */, - getResources().getString(R.string.home_work_profile_not_supported)); - } else { - pref = new HomeAppPreference(context, activityName, prefIndex, - icon, name, this, info, true /* enabled */, null); - } - - mPrefs.add(pref); - mPrefGroup.addPreference(pref); - if (activityName.equals(currentDefaultHome)) { - mCurrentHome = pref; - } - prefIndex++; - } catch (Exception e) { - Log.v(TAG, "Problem dealing with activity " + activityName, e); - } - } - - if (mCurrentHome != null) { - if (mCurrentHome.isEnabled()) { - getActivity().setResult(Activity.RESULT_OK); - } - - new Handler().post(new Runnable() { - public void run() { - mCurrentHome.setChecked(true); - } - }); - } - } - - private boolean hasManagedProfile() { - Context context = getActivity(); - UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); - List profiles = userManager.getProfiles(context.getUserId()); - for (UserInfo userInfo : profiles) { - if (userInfo.isManagedProfile()) return true; - } - return false; - } - - private boolean launcherHasManagedProfilesFeature(ResolveInfo resolveInfo) { - try { - ApplicationInfo appInfo = getPackageManager().getApplicationInfo( - resolveInfo.activityInfo.packageName, 0 /* default flags */); - return versionNumberAtLeastL(appInfo.targetSdkVersion); - } catch (PackageManager.NameNotFoundException e) { - return false; - } - } - - private boolean versionNumberAtLeastL(int versionNumber) { - return versionNumber >= Build.VERSION_CODES.LOLLIPOP; - } - - @Override - public int getMetricsCategory() { - return MetricsEvent.HOME; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.home_selection); - - mPm = getPackageManager(); - mPrefGroup = (PreferenceGroup) findPreference("home"); - - Bundle args = getArguments(); - mShowNotice = (args != null) && args.getBoolean(HOME_SHOW_NOTICE, false); - } - - @Override - public void onResume() { - super.onResume(); - - final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED); - filter.addAction(Intent.ACTION_PACKAGE_REMOVED); - filter.addAction(Intent.ACTION_PACKAGE_CHANGED); - filter.addAction(Intent.ACTION_PACKAGE_REPLACED); - filter.addDataScheme("package"); - getActivity().registerReceiver(mHomePackageReceiver, filter); - - buildHomeActivitiesList(); - } - - @Override - public void onPause() { - super.onPause(); - getActivity().unregisterReceiver(mHomePackageReceiver); - } - - private class HomeAppPreference extends Preference { - ComponentName activityName; - int index; - HomeSettings fragment; - final ColorFilter grayscaleFilter; - boolean isChecked; - - boolean isSystem; - String uninstallTarget; - - public HomeAppPreference(Context context, ComponentName activity, - int i, Drawable icon, CharSequence title, HomeSettings parent, ActivityInfo info, - boolean enabled, CharSequence summary) { - super(context); - setLayoutResource(R.layout.preference_home_app); - setIcon(icon); - setTitle(title); - setEnabled(enabled); - setSummary(summary); - activityName = activity; - fragment = parent; - index = i; - - ColorMatrix colorMatrix = new ColorMatrix(); - colorMatrix.setSaturation(0f); - float[] matrix = colorMatrix.getArray(); - matrix[18] = 0.5f; - grayscaleFilter = new ColorMatrixColorFilter(colorMatrix); - - determineTargets(info); - } - - // Check whether this activity is bundled on the system, with awareness - // of the META_HOME_ALTERNATE mechanism. - private void determineTargets(ActivityInfo info) { - final Bundle meta = info.metaData; - if (meta != null) { - final String altHomePackage = meta.getString(ActivityManager.META_HOME_ALTERNATE); - if (altHomePackage != null) { - try { - final int match = mPm.checkSignatures(info.packageName, altHomePackage); - if (match >= PackageManager.SIGNATURE_MATCH) { - PackageInfo altInfo = mPm.getPackageInfo(altHomePackage, 0); - final int altFlags = altInfo.applicationInfo.flags; - isSystem = (altFlags & ApplicationInfo.FLAG_SYSTEM) != 0; - uninstallTarget = altInfo.packageName; - return; - } - } catch (Exception e) { - // e.g. named alternate package not found during lookup - Log.w(TAG, "Unable to compare/resolve alternate", e); - } - } - } - // No suitable metadata redirect, so use the package's own info - isSystem = (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; - uninstallTarget = info.packageName; - } - - @Override - public void onBindViewHolder(PreferenceViewHolder view) { - super.onBindViewHolder(view); - - RadioButton radio = (RadioButton) view.findViewById(R.id.home_radio); - radio.setChecked(isChecked); - - Integer indexObj = new Integer(index); - - ImageView icon = (ImageView) view.findViewById(R.id.home_app_uninstall); - if (isSystem) { - icon.setEnabled(false); - icon.setColorFilter(grayscaleFilter); - } else { - icon.setEnabled(true); - icon.setOnClickListener(mDeleteClickListener); - icon.setTag(indexObj); - } - - View v = view.findViewById(R.id.home_app_pref); - v.setTag(indexObj); - - v.setOnClickListener(mHomeClickListener); - } - - void setChecked(boolean state) { - if (state != isChecked) { - isChecked = state; - notifyChanged(); - } - } - } - - /** - * For search - */ - public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider() { - @Override - public List getRawDataToIndex(Context context, boolean enabled) { - final List result = new ArrayList(); - - final PackageManager pm = context.getPackageManager(); - final ArrayList homeActivities = new ArrayList(); - pm.getHomeActivities(homeActivities); - - final SharedPreferences sp = context.getSharedPreferences( - HomeSettings.HOME_PREFS, Context.MODE_PRIVATE); - final boolean doShowHome = sp.getBoolean(HomeSettings.HOME_PREFS_DO_SHOW, false); - - // We index Home Launchers only if there are more than one or if we are showing the - // Home tile into the Dashboard - if (homeActivities.size() > 1 || doShowHome) { - final Resources res = context.getResources(); - - // Add fragment title - SearchIndexableRaw data = new SearchIndexableRaw(context); - data.title = res.getString(R.string.home_settings); - data.screenTitle = res.getString(R.string.home_settings); - data.keywords = res.getString(R.string.keywords_home); - result.add(data); - - for (int i = 0; i < homeActivities.size(); i++) { - final ResolveInfo resolveInfo = homeActivities.get(i); - final ActivityInfo activityInfo = resolveInfo.activityInfo; - - CharSequence name; - try { - name = activityInfo.loadLabel(pm); - if (TextUtils.isEmpty(name)) { - continue; - } - } catch (Exception e) { - Log.v(TAG, "Problem dealing with Home " + activityInfo.name, e); - continue; - } - - data = new SearchIndexableRaw(context); - data.title = name.toString(); - data.screenTitle = res.getString(R.string.home_settings); - result.add(data); - } - } - - return result; - } - }; -} diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 53fab730e40..edefaf712a0 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -64,9 +64,9 @@ import com.android.settings.fingerprint.FingerprintSettings; import com.android.settings.location.LocationPreferenceController; import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Index; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; +import com.android.settings.search2.SearchFeatureProvider; import com.android.settings.security.SecurityFeatureProvider; import com.android.settings.trustagent.TrustAgentManager; import com.android.settings.widget.GearPreference; @@ -79,7 +79,6 @@ import com.android.settingslib.drawer.TileUtils; import java.util.ArrayList; import java.util.concurrent.Executors; -import java.util.concurrent.ExecutorService; import java.util.List; import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT; @@ -366,7 +365,8 @@ public class SecuritySettings extends SettingsPreferenceFragment // The above preferences come and go based on security state, so we need to update // the index. This call is expected to be fairly cheap, but we may want to do something // smarter in the future. - Index.getInstance(getActivity()) + final Activity activity = getActivity(); + FeatureFactory.getFactory(activity).getSearchFeatureProvider().getIndexingManager(activity) .updateFromClassNameResource(SecuritySettings.class.getName(), true, true); PreferenceGroup securityStatusPreferenceGroup = diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index e438cbfc6ae..5bddffa28b3 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -38,8 +38,6 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.overlay.FeatureFactory; -import com.android.settings.search.Index; -import com.android.settings.search.SearchIndexableRaw; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.HidProfile; import com.android.settingslib.bluetooth.LocalBluetoothProfile; @@ -250,17 +248,6 @@ public final class BluetoothDevicePreference extends Preference implements if (!mCachedDevice.startPairing()) { Utils.showError(getContext(), mCachedDevice.getName(), R.string.bluetooth_pairing_error_message); - } else { - final Context context = getContext(); - - SearchIndexableRaw data = new SearchIndexableRaw(context); - data.className = BluetoothSettings.class.getName(); - data.title = mCachedDevice.getName(); - data.screenTitle = context.getResources().getString(R.string.bluetooth_settings); - data.iconResId = R.drawable.ic_settings_bluetooth; - data.enabled = true; - - Index.getInstance(context).updateFromSearchIndexableData(data); } } diff --git a/src/com/android/settings/bluetooth/BluetoothEnabler.java b/src/com/android/settings/bluetooth/BluetoothEnabler.java index 6db51dfc87c..22b21e4ceb8 100644 --- a/src/com/android/settings/bluetooth/BluetoothEnabler.java +++ b/src/com/android/settings/bluetooth/BluetoothEnabler.java @@ -21,15 +21,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.os.Handler; -import android.os.Message; import android.provider.Settings; import android.widget.Switch; import android.widget.Toast; import com.android.settings.R; import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.search.Index; import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.WirelessUtils; import com.android.settingslib.bluetooth.LocalBluetoothAdapter; @@ -53,19 +50,6 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh private static final int EVENT_UPDATE_INDEX = 0; private final int mMetricsEvent; - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_UPDATE_INDEX: - final boolean isBluetoothOn = msg.getData().getBoolean(EVENT_DATA_IS_BT_ON); - Index.getInstance(mContext).updateFromClassNameResource( - BluetoothSettings.class.getName(), true, isBluetoothOn); - break; - } - } - }; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -142,7 +126,6 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh case BluetoothAdapter.STATE_ON: setChecked(true); mSwitchWidget.setEnabled(true); - updateSearchIndex(true); break; case BluetoothAdapter.STATE_TURNING_OFF: mSwitchWidget.setEnabled(false); @@ -150,12 +133,10 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh case BluetoothAdapter.STATE_OFF: setChecked(false); mSwitchWidget.setEnabled(true); - updateSearchIndex(false); break; default: setChecked(false); mSwitchWidget.setEnabled(true); - updateSearchIndex(false); } } @@ -173,15 +154,6 @@ public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchCh } } - private void updateSearchIndex(boolean isBluetoothOn) { - mHandler.removeMessages(EVENT_UPDATE_INDEX); - - Message msg = new Message(); - msg.what = EVENT_UPDATE_INDEX; - msg.getData().putBoolean(EVENT_DATA_IS_BT_ON, isBluetoothOn); - mHandler.sendMessage(msg); - } - @Override public boolean onSwitchToggled(boolean isChecked) { // Show toast message if Bluetooth is not allowed in airplane mode diff --git a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java index b9efbf83c78..a6dfa9b4b48 100755 --- a/src/com/android/settings/bluetooth/DeviceProfilesSettings.java +++ b/src/com/android/settings/bluetooth/DeviceProfilesSettings.java @@ -18,7 +18,6 @@ package com.android.settings.bluetooth; import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; @@ -117,10 +116,6 @@ public final class DeviceProfilesSettings extends InstrumentedDialogFragment imp break; case DialogInterface.BUTTON_NEUTRAL: mCachedDevice.unpair(); - com.android.settings.bluetooth.Utils.updateSearchIndex(getContext(), - BluetoothSettings.class.getName(), mCachedDevice.getName(), - getString(R.string.bluetooth_settings), - R.drawable.ic_settings_bluetooth, false); break; } } diff --git a/src/com/android/settings/bluetooth/Utils.java b/src/com/android/settings/bluetooth/Utils.java index 037b381a033..eb194f4443b 100755 --- a/src/com/android/settings/bluetooth/Utils.java +++ b/src/com/android/settings/bluetooth/Utils.java @@ -27,8 +27,6 @@ import android.widget.Toast; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; -import com.android.settings.search.Index; -import com.android.settings.search.SearchIndexableRaw; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothManager.BluetoothManagerCallback; import com.android.settingslib.bluetooth.Utils.ErrorListener; @@ -116,21 +114,6 @@ public final class Utils { } } - /** - * Update the search Index for a specific class name and resources. - */ - public static void updateSearchIndex(Context context, String className, String title, - String screenTitle, int iconResId, boolean enabled) { - SearchIndexableRaw data = new SearchIndexableRaw(context); - data.className = className; - data.title = title; - data.screenTitle = screenTitle; - data.iconResId = iconResId; - data.enabled = enabled; - - Index.getInstance(context).updateFromSearchIndexableData(data); - } - public static LocalBluetoothManager getLocalBtManager(Context context) { return LocalBluetoothManager.getInstance(context, mOnInitCallback); } diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index 2a3c5d307df..f6cad2874ca 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -27,7 +27,6 @@ import com.android.settings.DeviceAdminSettings; import com.android.settings.DeviceInfoSettings; import com.android.settings.DisplaySettings; import com.android.settings.DreamSettings; -import com.android.settings.HomeSettings; import com.android.settings.IccLockSettings; import com.android.settings.MasterClear; import com.android.settings.PrivacySettings; @@ -148,7 +147,6 @@ public class SettingsGateway { SpellCheckersSettings.class.getName(), UserDictionaryList.class.getName(), UserDictionarySettings.class.getName(), - HomeSettings.class.getName(), DisplaySettings.class.getName(), DeviceInfoSettings.class.getName(), ManageApplications.class.getName(), diff --git a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java index d6fe1aa03bd..a46a62e524b 100644 --- a/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java +++ b/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java @@ -40,7 +40,7 @@ import com.android.settings.core.lifecycle.Lifecycle; import com.android.settings.core.lifecycle.LifecycleObserver; import com.android.settings.core.lifecycle.events.OnResume; import com.android.settings.overlay.FeatureFactory; -import com.android.settings.search.Index; +import com.android.settings.search2.SearchFeatureProvider; import com.android.settingslib.RestrictedLockUtils; public class BuildNumberPreferenceController extends PreferenceController @@ -221,8 +221,7 @@ public class BuildNumberPreferenceController extends PreferenceController Toast.LENGTH_LONG); mDevHitToast.show(); // This is good time to index the Developer Options - Index.getInstance( - mContext.getApplicationContext()).updateFromClassNameResource( - DevelopmentSettings.class.getName(), true, true); + FeatureFactory.getFactory(mContext).getSearchFeatureProvider().getIndexingManager(mContext) + .updateFromClassNameResource(DevelopmentSettings.class.getName(), true, true); } } diff --git a/src/com/android/settings/search/DynamicIndexableContentMonitor.java b/src/com/android/settings/search/DynamicIndexableContentMonitor.java index c91f381de21..b3672021833 100644 --- a/src/com/android/settings/search/DynamicIndexableContentMonitor.java +++ b/src/com/android/settings/search/DynamicIndexableContentMonitor.java @@ -52,7 +52,9 @@ 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 com.android.settings.search2.DatabaseIndexingManager; import java.util.ArrayList; import java.util.List; @@ -67,7 +69,7 @@ public final class DynamicIndexableContentMonitor implements private static final PackageChangeMonitor PACKAGE_CHANGE_MONITOR = new PackageChangeMonitor(); // Null if not initialized. - @Nullable private Index mIndex; + @Nullable private DatabaseIndexingManager mIndexManager; private Context mContext; private boolean mHasFeaturePrinting; @@ -112,22 +114,25 @@ public final class DynamicIndexableContentMonitor implements final boolean isUserUnlocked = activity .getSystemService(UserManager.class) .isUserUnlocked(); - register(activity, loaderId, Index.getInstance(activity), isUserUnlocked); + register(activity, loaderId, FeatureFactory.getFactory(activity) + .getSearchFeatureProvider().getIndexingManager(activity), isUserUnlocked); } /** - * For testing to inject {@link Index} object. Also because currently Robolectric doesn't - * support API 24, we can not test code that calls {@link UserManager#isUserUnlocked()}. + * 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, Index index, boolean isUserUnlocked) { + 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; - mIndex = index; + mIndexManager = indexManager; PACKAGE_CHANGE_MONITOR.registerMonitor(context); mHasFeaturePrinting = context.getPackageManager() @@ -137,11 +142,11 @@ public final class DynamicIndexableContentMonitor implements } // Watch for input device changes. - InputDevicesMonitor.getInstance().initialize(context, index); + InputDevicesMonitor.getInstance().initialize(context, mIndexManager); // Start tracking packages. - AccessibilityServicesMonitor.getInstance().initialize(context, index); - InputMethodServicesMonitor.getInstance().initialize(context, index); + AccessibilityServicesMonitor.getInstance().initialize(context, mIndexManager); + InputMethodServicesMonitor.getInstance().initialize(context, mIndexManager); } /** @@ -152,7 +157,7 @@ public final class DynamicIndexableContentMonitor implements * @param loaderId id for loading print services. */ public void unregister(Activity activity, int loaderId) { - if (mIndex == null) return; + if (mIndexManager == null) return; PACKAGE_CHANGE_MONITOR.unregisterMonitor(); if (mHasFeaturePrinting) { @@ -170,7 +175,7 @@ public final class DynamicIndexableContentMonitor implements @Override public void onLoadFinished(Loader> loader, List services) { - mIndex.updateFromClassNameResource(PrintSettingsFragment.class.getName(), + mIndexManager.updateFromClassNameResource(PrintSettingsFragment.class.getName(), false /* rebuild */, true /* includeInSearchResult */); } @@ -183,7 +188,7 @@ public final class DynamicIndexableContentMonitor implements private static class InputDevicesMonitor implements InputManager.InputDeviceListener { // Null if not initialized. - @Nullable private Index mIndex; + @Nullable private DatabaseIndexingManager mIndexManager; private InputManager mInputManager; private InputDevicesMonitor() {} @@ -198,15 +203,15 @@ public final class DynamicIndexableContentMonitor implements @VisibleForTesting synchronized void resetForTesting() { - if (mIndex != null) { + if (mIndexManager != null) { mInputManager.unregisterInputDeviceListener(this /* listener */); } - mIndex = null; + mIndexManager = null; } - synchronized void initialize(Context context, Index index) { - if (mIndex != null) return; - mIndex = index; + synchronized void initialize(Context context, DatabaseIndexingManager indexManager) { + if (mIndexManager != null) return; + mIndexManager = indexManager; mInputManager = (InputManager) context.getSystemService(Context.INPUT_SERVICE); buildIndex(true /* rebuild */); @@ -215,7 +220,7 @@ public final class DynamicIndexableContentMonitor implements } private void buildIndex(boolean rebuild) { - mIndex.updateFromClassNameResource(PhysicalKeyboardFragment.class.getName(), + mIndexManager.updateFromClassNameResource(PhysicalKeyboardFragment.class.getName(), rebuild, true /* includeInSearchResult */); } @@ -314,7 +319,7 @@ public final class DynamicIndexableContentMonitor implements private static class AccessibilityServicesMonitor { // Null if not initialized. - @Nullable private Index mIndex; + @Nullable private DatabaseIndexingManager mIndexManager; private PackageManager mPackageManager; private final List mAccessibilityServices = new ArrayList<>(); @@ -331,12 +336,12 @@ public final class DynamicIndexableContentMonitor implements @VisibleForTesting synchronized void resetForTesting() { - mIndex = null; + mIndexManager = null; } - synchronized void initialize(Context context, Index index) { - if (mIndex != null) return; - mIndex = index; + synchronized void initialize(Context context, DatabaseIndexingManager index) { + if (mIndexManager != null) return; + mIndexManager = index; mPackageManager = context.getPackageManager(); mAccessibilityServices.clear(); buildIndex(true /* rebuild */); @@ -354,12 +359,12 @@ public final class DynamicIndexableContentMonitor implements } private void buildIndex(boolean rebuild) { - mIndex.updateFromClassNameResource(AccessibilitySettings.class.getName(), + mIndexManager.updateFromClassNameResource(AccessibilitySettings.class.getName(), rebuild, true /* includeInSearchResult */); } synchronized void onPackageAvailable(String packageName) { - if (mIndex == null) return; + if (mIndexManager == null) return; if (mAccessibilityServices.contains(packageName)) return; final Intent intent = getAccessibilityServiceIntent(packageName); @@ -371,7 +376,7 @@ public final class DynamicIndexableContentMonitor implements } synchronized void onPackageUnavailable(String packageName) { - if (mIndex == null) return; + if (mIndexManager == null) return; if (!mAccessibilityServices.remove(packageName)) return; buildIndex(true /* rebuild */); } @@ -385,7 +390,7 @@ public final class DynamicIndexableContentMonitor implements Settings.Secure.getUriFor(Settings.Secure.ENABLED_INPUT_METHODS); // Null if not initialized. - @Nullable private Index mIndex; + @Nullable private DatabaseIndexingManager mIndexManager; private PackageManager mPackageManager; private ContentResolver mContentResolver; private final List mInputMethodServices = new ArrayList<>(); @@ -406,19 +411,19 @@ public final class DynamicIndexableContentMonitor implements @VisibleForTesting synchronized void resetForTesting() { - if (mIndex != null) { + if (mIndexManager != null) { mContentResolver.unregisterContentObserver(this /* observer */); } - mIndex = null; + mIndexManager = null; } - synchronized void initialize(Context context, Index index) { + synchronized void initialize(Context context, DatabaseIndexingManager indexManager) { final boolean hasFeatureIme = context.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS); if (!hasFeatureIme) return; - if (mIndex != null) return; - mIndex = index; + if (mIndexManager != null) return; + mIndexManager = indexManager; mPackageManager = context.getPackageManager(); mContentResolver = context.getContentResolver(); mInputMethodServices.clear(); @@ -448,12 +453,12 @@ public final class DynamicIndexableContentMonitor implements } private void buildIndex(Class indexClass, boolean rebuild) { - mIndex.updateFromClassNameResource(indexClass.getName(), rebuild, + mIndexManager.updateFromClassNameResource(indexClass.getName(), rebuild, true /* includeInSearchResult */); } synchronized void onPackageAvailable(String packageName) { - if (mIndex == null) return; + if (mIndexManager == null) return; if (mInputMethodServices.contains(packageName)) return; final Intent intent = getIMEServiceIntent(packageName); @@ -466,7 +471,7 @@ public final class DynamicIndexableContentMonitor implements } synchronized void onPackageUnavailable(String packageName) { - if (mIndex == null) return; + if (mIndexManager == null) return; if (!mInputMethodServices.remove(packageName)) return; buildIndex(VirtualKeyboardFragment.class, true /* rebuild */); buildIndex(AvailableVirtualKeyboardFragment.class, true /* rebuild */); diff --git a/src/com/android/settings/search/Index.java b/src/com/android/settings/search/Index.java deleted file mode 100644 index 879bd772f6f..00000000000 --- a/src/com/android/settings/search/Index.java +++ /dev/null @@ -1,1336 +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.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.database.MergeCursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteException; -import android.database.sqlite.SQLiteFullException; -import android.net.Uri; -import android.os.AsyncTask; -import android.provider.SearchIndexableData; -import android.provider.SearchIndexableResource; -import android.provider.SearchIndexablesContract; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.util.Xml; - -import com.android.settings.R; -import com.android.settings.search.IndexDatabaseHelper.IndexColumns; -import com.android.settings.search.IndexDatabaseHelper.Tables; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.lang.reflect.Field; -import java.text.Normalizer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Pattern; - -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_RANK; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_USER_ID; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK; -import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID; - -public class Index { - - private static final String LOG_TAG = "Index"; - - // Those indices should match the indices of SELECT_COLUMNS ! - public static final int COLUMN_INDEX_RANK = 0; - public static final int COLUMN_INDEX_TITLE = 1; - public static final int COLUMN_INDEX_SUMMARY_ON = 2; - public static final int COLUMN_INDEX_SUMMARY_OFF = 3; - public static final int COLUMN_INDEX_ENTRIES = 4; - public static final int COLUMN_INDEX_KEYWORDS = 5; - public static final int COLUMN_INDEX_CLASS_NAME = 6; - public static final int COLUMN_INDEX_SCREEN_TITLE = 7; - public static final int COLUMN_INDEX_ICON = 8; - public static final int COLUMN_INDEX_INTENT_ACTION = 9; - public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE = 10; - public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS = 11; - public static final int COLUMN_INDEX_ENABLED = 12; - public static final int COLUMN_INDEX_KEY = 13; - public static final int COLUMN_INDEX_USER_ID = 14; - - public static final String ENTRIES_SEPARATOR = "|"; - - static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER = - "SEARCH_INDEX_DATA_PROVIDER"; - - // If you change the order of columns here, you SHOULD change the COLUMN_INDEX_XXX values - private static final String[] SELECT_COLUMNS = new String[] { - IndexColumns.DATA_RANK, // 0 - IndexColumns.DATA_TITLE, // 1 - IndexColumns.DATA_SUMMARY_ON, // 2 - IndexColumns.DATA_SUMMARY_OFF, // 3 - IndexColumns.DATA_ENTRIES, // 4 - IndexColumns.DATA_KEYWORDS, // 5 - IndexColumns.CLASS_NAME, // 6 - IndexColumns.SCREEN_TITLE, // 7 - IndexColumns.ICON, // 8 - IndexColumns.INTENT_ACTION, // 9 - IndexColumns.INTENT_TARGET_PACKAGE, // 10 - IndexColumns.INTENT_TARGET_CLASS, // 11 - IndexColumns.ENABLED, // 12 - IndexColumns.DATA_KEY_REF // 13 - }; - - private static final String[] MATCH_COLUMNS_PRIMARY = { - IndexColumns.DATA_TITLE, - IndexColumns.DATA_TITLE_NORMALIZED, - IndexColumns.DATA_KEYWORDS - }; - - private static final String[] MATCH_COLUMNS_SECONDARY = { - IndexColumns.DATA_SUMMARY_ON, - IndexColumns.DATA_SUMMARY_ON_NORMALIZED, - IndexColumns.DATA_SUMMARY_OFF, - IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, - IndexColumns.DATA_ENTRIES - }; - - // Max number of saved search queries (who will be used for proposing suggestions) - private static long MAX_SAVED_SEARCH_QUERY = 64; - // Max number of proposed suggestions - private static final int MAX_PROPOSED_SUGGESTIONS = 5; - - private static final String BASE_AUTHORITY = "com.android.settings"; - - private static final String EMPTY = ""; - private static final String NON_BREAKING_HYPHEN = "\u2011"; - private static final String LIST_DELIMITERS = "[,]\\s*"; - private static final String HYPHEN = "-"; - private static final String SPACE = " "; - - private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; - private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference"; - private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference"; - - private static final List EMPTY_LIST = Collections.emptyList(); - - private static Index sInstance; - - private static final Pattern REMOVE_DIACRITICALS_PATTERN - = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); - - /** - * A private class to describe the update data for the Index database - */ - private static class UpdateData { - public List dataToUpdate; - public List dataToDelete; - public Map> nonIndexableKeys; - - public boolean forceUpdate; - public boolean fullIndex; - - public UpdateData() { - dataToUpdate = new ArrayList(); - dataToDelete = new ArrayList(); - nonIndexableKeys = new HashMap>(); - } - - public UpdateData(UpdateData other) { - dataToUpdate = new ArrayList(other.dataToUpdate); - dataToDelete = new ArrayList(other.dataToDelete); - nonIndexableKeys = new HashMap>(other.nonIndexableKeys); - forceUpdate = other.forceUpdate; - fullIndex = other.fullIndex; - } - - public UpdateData copy() { - return new UpdateData(this); - } - - public void clear() { - dataToUpdate.clear(); - dataToDelete.clear(); - nonIndexableKeys.clear(); - forceUpdate = false; - fullIndex = false; - } - } - - private final AtomicBoolean mIsAvailable = new AtomicBoolean(false); - private final UpdateData mDataToProcess = new UpdateData(); - private Context mContext; - private final String mBaseAuthority; - - /** - * A basic singleton - */ - public static Index getInstance(Context context) { - if (sInstance == null) { - synchronized (Index.class) { - if (sInstance == null) { - sInstance = new Index(context.getApplicationContext(), BASE_AUTHORITY); - } - } - } - return sInstance; - } - - private Index(Context context, String baseAuthority) { - mContext = context; - mBaseAuthority = baseAuthority; - } - - public boolean isAvailable() { - return mIsAvailable.get(); - } - - public Cursor search(String query) { - final SQLiteDatabase database = getReadableDatabase(); - final Cursor[] cursors = new Cursor[2]; - - final String primarySql = buildSearchSQL(query, MATCH_COLUMNS_PRIMARY, true); - Log.d(LOG_TAG, "Search primary query: " + primarySql); - cursors[0] = database.rawQuery(primarySql, null); - - // We need to use an EXCEPT operator as negate MATCH queries do not work. - StringBuilder sql = new StringBuilder( - buildSearchSQL(query, MATCH_COLUMNS_SECONDARY, false)); - sql.append(" EXCEPT "); - sql.append(primarySql); - - final String secondarySql = sql.toString(); - Log.d(LOG_TAG, "Search secondary query: " + secondarySql); - cursors[1] = database.rawQuery(secondarySql, null); - - return new MergeCursor(cursors); - } - - public Cursor getSuggestions(String query) { - final String sql = buildSuggestionsSQL(query); - Log.d(LOG_TAG, "Suggestions query: " + sql); - return getReadableDatabase().rawQuery(sql, null); - } - - private String buildSuggestionsSQL(String query) { - StringBuilder sb = new StringBuilder(); - - sb.append("SELECT "); - sb.append(IndexDatabaseHelper.SavedQueriesColumns.QUERY); - sb.append(" FROM "); - sb.append(Tables.TABLE_SAVED_QUERIES); - - if (TextUtils.isEmpty(query)) { - sb.append(" ORDER BY rowId DESC"); - } else { - sb.append(" WHERE "); - sb.append(IndexDatabaseHelper.SavedQueriesColumns.QUERY); - sb.append(" LIKE "); - sb.append("'"); - sb.append(query); - sb.append("%"); - sb.append("'"); - } - - sb.append(" LIMIT "); - sb.append(MAX_PROPOSED_SUGGESTIONS); - - return sb.toString(); - } - - public long addSavedQuery(String query){ - final SaveSearchQueryTask task = new SaveSearchQueryTask(); - task.execute(query); - try { - return task.get(); - } catch (InterruptedException e) { - Log.e(LOG_TAG, "Cannot insert saved query: " + query, e); - return -1 ; - } catch (ExecutionException e) { - Log.e(LOG_TAG, "Cannot insert saved query: " + query, e); - return -1; - } - } - - public void update() { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE); - List list = - mContext.getPackageManager().queryIntentContentProviders(intent, 0); - - final int size = list.size(); - for (int n = 0; n < size; n++) { - final ResolveInfo info = list.get(n); - if (!isWellKnownProvider(info)) { - continue; - } - final String authority = info.providerInfo.authority; - final String packageName = info.providerInfo.packageName; - - addIndexablesFromRemoteProvider(packageName, authority); - addNonIndexablesKeysFromRemoteProvider(packageName, authority); - } - - mDataToProcess.fullIndex = true; - updateInternal(); - } - }); - } - - private boolean addIndexablesFromRemoteProvider(String packageName, String authority) { - try { - final int baseRank = 0; - - final Context context = mBaseAuthority.equals(authority) ? - mContext : mContext.createPackageContext(packageName, 0); - - final Uri uriForResources = buildUriForXmlResources(authority); - addIndexablesForXmlResourceUri(context, packageName, uriForResources, - SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS, baseRank); - - final Uri uriForRawData = buildUriForRawData(authority); - addIndexablesForRawDataUri(context, packageName, uriForRawData, - SearchIndexablesContract.INDEXABLES_RAW_COLUMNS, baseRank); - return true; - } catch (PackageManager.NameNotFoundException e) { - Log.w(LOG_TAG, "Could not create context for " + packageName + ": " - + Log.getStackTraceString(e)); - return false; - } - } - - private void addNonIndexablesKeysFromRemoteProvider(String packageName, - String authority) { - final List keys = - getNonIndexablesKeysFromRemoteProvider(packageName, authority); - addNonIndexableKeys(packageName, keys); - } - - private List getNonIndexablesKeysFromRemoteProvider(String packageName, - String authority) { - try { - final Context packageContext = mContext.createPackageContext(packageName, 0); - - final Uri uriForNonIndexableKeys = buildUriForNonIndexableKeys(authority); - return getNonIndexablesKeys(packageContext, uriForNonIndexableKeys, - SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS); - } catch (PackageManager.NameNotFoundException e) { - Log.w(LOG_TAG, "Could not create context for " + packageName + ": " - + Log.getStackTraceString(e)); - return EMPTY_LIST; - } - } - - private List getNonIndexablesKeys(Context packageContext, Uri uri, - String[] projection) { - - final ContentResolver resolver = packageContext.getContentResolver(); - final Cursor cursor = resolver.query(uri, projection, null, null, null); - - if (cursor == null) { - Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString()); - return EMPTY_LIST; - } - - List result = new ArrayList(); - try { - final int count = cursor.getCount(); - if (count > 0) { - while (cursor.moveToNext()) { - final String key = cursor.getString(COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE); - result.add(key); - } - } - return result; - } finally { - cursor.close(); - } - } - - public void addIndexableData(SearchIndexableData data) { - synchronized (mDataToProcess) { - mDataToProcess.dataToUpdate.add(data); - } - } - - public void addIndexableData(SearchIndexableResource[] array) { - synchronized (mDataToProcess) { - final int count = array.length; - for (int n = 0; n < count; n++) { - mDataToProcess.dataToUpdate.add(array[n]); - } - } - } - - public void deleteIndexableData(SearchIndexableData data) { - synchronized (mDataToProcess) { - mDataToProcess.dataToDelete.add(data); - } - } - - public void addNonIndexableKeys(String authority, List keys) { - synchronized (mDataToProcess) { - mDataToProcess.nonIndexableKeys.put(authority, keys); - } - } - - /** - * Only allow a "well known" SearchIndexablesProvider. The provider should: - * - * - have read/write {@link android.Manifest.permission#READ_SEARCH_INDEXABLES} - * - be from a privileged package - */ - private boolean isWellKnownProvider(ResolveInfo info) { - final String authority = info.providerInfo.authority; - final String packageName = info.providerInfo.applicationInfo.packageName; - - if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(packageName)) { - return false; - } - - final String readPermission = info.providerInfo.readPermission; - final String writePermission = info.providerInfo.writePermission; - - if (TextUtils.isEmpty(readPermission) || TextUtils.isEmpty(writePermission)) { - return false; - } - - if (!android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(readPermission) || - !android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(writePermission)) { - return false; - } - - return isPrivilegedPackage(packageName); - } - - private boolean isPrivilegedPackage(String packageName) { - final PackageManager pm = mContext.getPackageManager(); - try { - PackageInfo packInfo = pm.getPackageInfo(packageName, 0); - return ((packInfo.applicationInfo.privateFlags - & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); - } catch (PackageManager.NameNotFoundException e) { - return false; - } - } - - private void updateFromRemoteProvider(String packageName, String authority) { - if (addIndexablesFromRemoteProvider(packageName, authority)) { - updateInternal(); - } - } - - /** - * Update the Index for a specific class name resources - * - * @param className the class name (typically a fragment name). - * @param rebuild true means that you want to delete the data from the Index first. - * @param includeInSearchResults true means that you want the bit "enabled" set so that the - * data will be seen included into the search results - */ - public void updateFromClassNameResource(String className, final boolean rebuild, - boolean includeInSearchResults) { - if (className == null) { - throw new IllegalArgumentException("class name cannot be null!"); - } - final SearchIndexableResource res = SearchIndexableResources.getResourceByName(className); - if (res == null ) { - Log.e(LOG_TAG, "Cannot find SearchIndexableResources for class name: " + className); - return; - } - res.context = mContext; - res.enabled = includeInSearchResults; - AsyncTask.execute(new Runnable() { - @Override - public void run() { - if (rebuild) { - deleteIndexableData(res); - } - addIndexableData(res); - mDataToProcess.forceUpdate = true; - updateInternal(); - res.enabled = false; - } - }); - } - - public void updateFromSearchIndexableData(SearchIndexableData data) { - AsyncTask.execute(new Runnable() { - @Override - public void run() { - addIndexableData(data); - mDataToProcess.forceUpdate = true; - updateInternal(); - } - }); - } - - private SQLiteDatabase getReadableDatabase() { - return IndexDatabaseHelper.getInstance(mContext).getReadableDatabase(); - } - - private SQLiteDatabase getWritableDatabase() { - try { - return IndexDatabaseHelper.getInstance(mContext).getWritableDatabase(); - } catch (SQLiteException e) { - Log.e(LOG_TAG, "Cannot open writable database", e); - return null; - } - } - - private static Uri buildUriForXmlResources(String authority) { - return Uri.parse("content://" + authority + "/" + - SearchIndexablesContract.INDEXABLES_XML_RES_PATH); - } - - private static Uri buildUriForRawData(String authority) { - return Uri.parse("content://" + authority + "/" + - SearchIndexablesContract.INDEXABLES_RAW_PATH); - } - - private static Uri buildUriForNonIndexableKeys(String authority) { - return Uri.parse("content://" + authority + "/" + - SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH); - } - - private void updateInternal() { - synchronized (mDataToProcess) { - final UpdateIndexTask task = new UpdateIndexTask(); - UpdateData copy = mDataToProcess.copy(); - task.execute(copy); - mDataToProcess.clear(); - } - } - - private void addIndexablesForXmlResourceUri(Context packageContext, String packageName, - Uri uri, String[] projection, int baseRank) { - - final ContentResolver resolver = packageContext.getContentResolver(); - final Cursor cursor = resolver.query(uri, projection, null, null, null); - - if (cursor == null) { - Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString()); - return; - } - - try { - final int count = cursor.getCount(); - if (count > 0) { - while (cursor.moveToNext()) { - final int providerRank = cursor.getInt(COLUMN_INDEX_XML_RES_RANK); - final int rank = (providerRank > 0) ? baseRank + providerRank : baseRank; - - final int xmlResId = cursor.getInt(COLUMN_INDEX_XML_RES_RESID); - - final String className = cursor.getString(COLUMN_INDEX_XML_RES_CLASS_NAME); - final int iconResId = cursor.getInt(COLUMN_INDEX_XML_RES_ICON_RESID); - - final String action = cursor.getString(COLUMN_INDEX_XML_RES_INTENT_ACTION); - final String targetPackage = cursor.getString( - COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE); - final String targetClass = cursor.getString( - COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS); - - SearchIndexableResource sir = new SearchIndexableResource(packageContext); - sir.rank = rank; - sir.xmlResId = xmlResId; - sir.className = className; - sir.packageName = packageName; - sir.iconResId = iconResId; - sir.intentAction = action; - sir.intentTargetPackage = targetPackage; - sir.intentTargetClass = targetClass; - - addIndexableData(sir); - } - } - } finally { - cursor.close(); - } - } - - private void addIndexablesForRawDataUri(Context packageContext, String packageName, - Uri uri, String[] projection, int baseRank) { - - final ContentResolver resolver = packageContext.getContentResolver(); - final Cursor cursor = resolver.query(uri, projection, null, null, null); - - if (cursor == null) { - Log.w(LOG_TAG, "Cannot add index data for Uri: " + uri.toString()); - return; - } - - try { - final int count = cursor.getCount(); - if (count > 0) { - while (cursor.moveToNext()) { - final int providerRank = cursor.getInt(COLUMN_INDEX_RAW_RANK); - final int rank = (providerRank > 0) ? baseRank + providerRank : baseRank; - - final String title = cursor.getString(COLUMN_INDEX_RAW_TITLE); - final String summaryOn = cursor.getString(COLUMN_INDEX_RAW_SUMMARY_ON); - final String summaryOff = cursor.getString(COLUMN_INDEX_RAW_SUMMARY_OFF); - final String entries = cursor.getString(COLUMN_INDEX_RAW_ENTRIES); - final String keywords = cursor.getString(COLUMN_INDEX_RAW_KEYWORDS); - - final String screenTitle = cursor.getString(COLUMN_INDEX_RAW_SCREEN_TITLE); - - final String className = cursor.getString(COLUMN_INDEX_RAW_CLASS_NAME); - final int iconResId = cursor.getInt(COLUMN_INDEX_RAW_ICON_RESID); - - final String action = cursor.getString(COLUMN_INDEX_RAW_INTENT_ACTION); - final String targetPackage = cursor.getString( - COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE); - final String targetClass = cursor.getString( - COLUMN_INDEX_RAW_INTENT_TARGET_CLASS); - - final String key = cursor.getString(COLUMN_INDEX_RAW_KEY); - final int userId = cursor.getInt(COLUMN_INDEX_RAW_USER_ID); - - SearchIndexableRaw data = new SearchIndexableRaw(packageContext); - data.rank = rank; - data.title = title; - data.summaryOn = summaryOn; - data.summaryOff = summaryOff; - data.entries = entries; - data.keywords = keywords; - data.screenTitle = screenTitle; - data.className = className; - data.packageName = packageName; - data.iconResId = iconResId; - data.intentAction = action; - data.intentTargetPackage = targetPackage; - data.intentTargetClass = targetClass; - data.key = key; - data.userId = userId; - - addIndexableData(data); - } - } - } finally { - cursor.close(); - } - } - - private String buildSearchSQL(String query, String[] colums, boolean withOrderBy) { - StringBuilder sb = new StringBuilder(); - sb.append(buildSearchSQLForColumn(query, colums)); - if (withOrderBy) { - sb.append(" ORDER BY "); - sb.append(IndexColumns.DATA_RANK); - } - return sb.toString(); - } - - private String buildSearchSQLForColumn(String query, String[] columnNames) { - StringBuilder sb = new StringBuilder(); - sb.append("SELECT "); - for (int n = 0; n < SELECT_COLUMNS.length; n++) { - sb.append(SELECT_COLUMNS[n]); - if (n < SELECT_COLUMNS.length - 1) { - sb.append(", "); - } - } - sb.append(" FROM "); - sb.append(Tables.TABLE_PREFS_INDEX); - sb.append(" WHERE "); - sb.append(buildSearchWhereStringForColumns(query, columnNames)); - - return sb.toString(); - } - - private String buildSearchWhereStringForColumns(String query, String[] columnNames) { - final StringBuilder sb = new StringBuilder(Tables.TABLE_PREFS_INDEX); - sb.append(" MATCH "); - DatabaseUtils.appendEscapedSQLString(sb, - buildSearchMatchStringForColumns(query, columnNames)); - sb.append(" AND "); - sb.append(IndexColumns.LOCALE); - sb.append(" = "); - DatabaseUtils.appendEscapedSQLString(sb, Locale.getDefault().toString()); - sb.append(" AND "); - sb.append(IndexColumns.ENABLED); - sb.append(" = 1"); - return sb.toString(); - } - - private String buildSearchMatchStringForColumns(String query, String[] columnNames) { - final String value = (query != null ? query.trim() : "") + "*"; - StringBuilder sb = new StringBuilder(); - final int count = columnNames.length; - for (int n = 0; n < count; n++) { - sb.append(columnNames[n]); - sb.append(":"); - sb.append(value); - if (n < count - 1) { - sb.append(" OR "); - } - } - return sb.toString(); - } - - private void indexOneSearchIndexableData(SQLiteDatabase database, String localeStr, - SearchIndexableData data, Map> nonIndexableKeys) { - if (data instanceof SearchIndexableResource) { - indexOneResource(database, localeStr, (SearchIndexableResource) data, nonIndexableKeys); - } else if (data instanceof SearchIndexableRaw) { - indexOneRaw(database, localeStr, (SearchIndexableRaw) data); - } - } - - private void indexOneRaw(SQLiteDatabase database, String localeStr, - SearchIndexableRaw raw) { - // Should be the same locale as the one we are processing - if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { - return; - } - - updateOneRowWithFilteredData(database, localeStr, - raw.title, - raw.summaryOn, - raw.summaryOff, - raw.entries, - raw.className, - raw.screenTitle, - raw.iconResId, - raw.rank, - raw.keywords, - raw.intentAction, - raw.intentTargetPackage, - raw.intentTargetClass, - raw.enabled, - raw.key, - raw.userId); - } - - private static boolean isIndexableClass(final Class clazz) { - return (clazz != null) && Indexable.class.isAssignableFrom(clazz); - } - - private static Class getIndexableClass(String className) { - final Class clazz; - try { - clazz = Class.forName(className); - } catch (ClassNotFoundException e) { - Log.d(LOG_TAG, "Cannot find class: " + className); - return null; - } - return isIndexableClass(clazz) ? clazz : null; - } - - private void indexOneResource(SQLiteDatabase database, String localeStr, - SearchIndexableResource sir, Map> nonIndexableKeysFromResource) { - - if (sir == null) { - Log.e(LOG_TAG, "Cannot index a null resource!"); - return; - } - - final List nonIndexableKeys = new ArrayList(); - - if (sir.xmlResId > SearchIndexableResources.NO_DATA_RES_ID) { - List resNonIndxableKeys = nonIndexableKeysFromResource.get(sir.packageName); - if (resNonIndxableKeys != null && resNonIndxableKeys.size() > 0) { - nonIndexableKeys.addAll(resNonIndxableKeys); - } - - indexFromResource(sir.context, database, localeStr, - sir.xmlResId, sir.className, sir.iconResId, sir.rank, - sir.intentAction, sir.intentTargetPackage, sir.intentTargetClass, - nonIndexableKeys); - } else { - if (TextUtils.isEmpty(sir.className)) { - Log.w(LOG_TAG, "Cannot index an empty Search Provider name!"); - return; - } - - final Class clazz = getIndexableClass(sir.className); - if (clazz == null) { - Log.d(LOG_TAG, "SearchIndexableResource '" + sir.className + - "' should implement the " + Indexable.class.getName() + " interface!"); - return; - } - - // Will be non null only for a Local provider implementing a - // SEARCH_INDEX_DATA_PROVIDER field - final Indexable.SearchIndexProvider provider = getSearchIndexProvider(clazz); - if (provider != null) { - List providerNonIndexableKeys = provider.getNonIndexableKeys(sir.context); - if (providerNonIndexableKeys != null && providerNonIndexableKeys.size() > 0) { - nonIndexableKeys.addAll(providerNonIndexableKeys); - } - - indexFromProvider(mContext, database, localeStr, provider, sir.className, - sir.iconResId, sir.rank, sir.enabled, nonIndexableKeys); - } - } - } - - private Indexable.SearchIndexProvider getSearchIndexProvider(final Class clazz) { - try { - final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); - return (Indexable.SearchIndexProvider) f.get(null); - } catch (NoSuchFieldException e) { - Log.d(LOG_TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); - } catch (SecurityException se) { - Log.d(LOG_TAG, - "Security exception for field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); - } catch (IllegalAccessException e) { - Log.d(LOG_TAG, - "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); - } catch (IllegalArgumentException e) { - Log.d(LOG_TAG, - "Illegal argument when accessing field '" + - FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); - } - return null; - } - - private void indexFromResource(Context context, SQLiteDatabase database, String localeStr, - int xmlResId, String fragmentName, int iconResId, int rank, - String intentAction, String intentTargetPackage, String intentTargetClass, - List nonIndexableKeys) { - - XmlResourceParser parser = null; - try { - parser = context.getResources().getXml(xmlResId); - - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && type != XmlPullParser.START_TAG) { - // Parse next until start tag is found - } - - String nodeName = parser.getName(); - if (!NODE_NAME_PREFERENCE_SCREEN.equals(nodeName)) { - throw new RuntimeException( - "XML document must start with tag; found" - + nodeName + " at " + parser.getPositionDescription()); - } - - final int outerDepth = parser.getDepth(); - final AttributeSet attrs = Xml.asAttributeSet(parser); - - final String screenTitle = getDataTitle(context, attrs); - - String key = getDataKey(context, attrs); - - String title; - String summary; - String keywords; - - // Insert rows for the main PreferenceScreen node. Rewrite the data for removing - // hyphens. - if (!nonIndexableKeys.contains(key)) { - title = getDataTitle(context, attrs); - summary = getDataSummary(context, attrs); - keywords = getDataKeywords(context, attrs); - - updateOneRowWithFilteredData(database, localeStr, title, summary, null, null, - fragmentName, screenTitle, iconResId, rank, - keywords, intentAction, intentTargetPackage, intentTargetClass, true, - key, -1 /* default user id */); - } - - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - nodeName = parser.getName(); - - key = getDataKey(context, attrs); - if (nonIndexableKeys.contains(key)) { - continue; - } - - title = getDataTitle(context, attrs); - keywords = getDataKeywords(context, attrs); - - if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) { - summary = getDataSummary(context, attrs); - - String entries = null; - - if (nodeName.endsWith(NODE_NAME_LIST_PREFERENCE)) { - entries = getDataEntries(context, attrs); - } - - // Insert rows for the child nodes of PreferenceScreen - updateOneRowWithFilteredData(database, localeStr, title, summary, null, entries, - fragmentName, screenTitle, iconResId, rank, - keywords, intentAction, intentTargetPackage, intentTargetClass, - true, key, -1 /* default user id */); - } else { - String summaryOn = getDataSummaryOn(context, attrs); - String summaryOff = getDataSummaryOff(context, attrs); - - if (TextUtils.isEmpty(summaryOn) && TextUtils.isEmpty(summaryOff)) { - summaryOn = getDataSummary(context, attrs); - } - - updateOneRowWithFilteredData(database, localeStr, title, summaryOn, summaryOff, - null, fragmentName, screenTitle, iconResId, rank, - keywords, intentAction, intentTargetPackage, intentTargetClass, - true, key, -1 /* default user id */); - } - } - - } catch (XmlPullParserException e) { - throw new RuntimeException("Error parsing PreferenceScreen", e); - } catch (IOException e) { - throw new RuntimeException("Error parsing PreferenceScreen", e); - } finally { - if (parser != null) parser.close(); - } - } - - private void indexFromProvider(Context context, SQLiteDatabase database, String localeStr, - Indexable.SearchIndexProvider provider, String className, int iconResId, int rank, - boolean enabled, List nonIndexableKeys) { - - if (provider == null) { - Log.w(LOG_TAG, "Cannot find provider: " + className); - return; - } - - final List rawList = provider.getRawDataToIndex(context, enabled); - - if (rawList != null) { - final int rawSize = rawList.size(); - for (int i = 0; i < rawSize; i++) { - SearchIndexableRaw raw = rawList.get(i); - - // Should be the same locale as the one we are processing - if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { - continue; - } - - if (nonIndexableKeys.contains(raw.key)) { - continue; - } - - updateOneRowWithFilteredData(database, localeStr, - raw.title, - raw.summaryOn, - raw.summaryOff, - raw.entries, - className, - raw.screenTitle, - iconResId, - rank, - raw.keywords, - raw.intentAction, - raw.intentTargetPackage, - raw.intentTargetClass, - raw.enabled, - raw.key, - raw.userId); - } - } - - final List resList = - provider.getXmlResourcesToIndex(context, enabled); - if (resList != null) { - final int resSize = resList.size(); - for (int i = 0; i < resSize; i++) { - SearchIndexableResource item = resList.get(i); - - // Should be the same locale as the one we are processing - if (!item.locale.toString().equalsIgnoreCase(localeStr)) { - continue; - } - - final int itemIconResId = (item.iconResId == 0) ? iconResId : item.iconResId; - final int itemRank = (item.rank == 0) ? rank : item.rank; - String itemClassName = (TextUtils.isEmpty(item.className)) - ? className : item.className; - - indexFromResource(context, database, localeStr, - item.xmlResId, itemClassName, itemIconResId, itemRank, - item.intentAction, item.intentTargetPackage, - item.intentTargetClass, nonIndexableKeys); - } - } - } - - private void updateOneRowWithFilteredData(SQLiteDatabase database, String locale, - String title, String summaryOn, String summaryOff, String entries, - String className, - String screenTitle, int iconResId, int rank, String keywords, - String intentAction, String intentTargetPackage, String intentTargetClass, - boolean enabled, String key, int userId) { - - final String updatedTitle = normalizeHyphen(title); - final String updatedSummaryOn = normalizeHyphen(summaryOn); - final String updatedSummaryOff = normalizeHyphen(summaryOff); - - final String normalizedTitle = normalizeString(updatedTitle); - final String normalizedSummaryOn = normalizeString(updatedSummaryOn); - final String normalizedSummaryOff = normalizeString(updatedSummaryOff); - - final String spaceDelimitedKeywords = normalizeKeywords(keywords); - - updateOneRow(database, locale, - updatedTitle, normalizedTitle, updatedSummaryOn, normalizedSummaryOn, - updatedSummaryOff, normalizedSummaryOff, entries, className, screenTitle, iconResId, - rank, spaceDelimitedKeywords, intentAction, intentTargetPackage, intentTargetClass, - enabled, key, userId); - } - - private static String normalizeHyphen(String input) { - return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY; - } - - private static String normalizeString(String input) { - final String nohyphen = (input != null) ? input.replaceAll(HYPHEN, EMPTY) : EMPTY; - final String normalized = Normalizer.normalize(nohyphen, Normalizer.Form.NFD); - - return REMOVE_DIACRITICALS_PATTERN.matcher(normalized).replaceAll("").toLowerCase(); - } - - private static String normalizeKeywords(String input) { - return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY; - } - - private void updateOneRow(SQLiteDatabase database, String locale, String updatedTitle, - String normalizedTitle, String updatedSummaryOn, String normalizedSummaryOn, - String updatedSummaryOff, String normalizedSummaryOff, String entries, String className, - String screenTitle, int iconResId, int rank, String spaceDelimitedKeywords, - String intentAction, String intentTargetPackage, String intentTargetClass, - boolean enabled, String key, int userId) { - - if (TextUtils.isEmpty(updatedTitle)) { - return; - } - - // The DocID should contains more than the title string itself (you may have two settings - // with the same title). So we need to use a combination of the title and the screenTitle. - StringBuilder sb = new StringBuilder(updatedTitle); - sb.append(screenTitle); - int docId = sb.toString().hashCode(); - - ContentValues values = new ContentValues(); - values.put(IndexColumns.DOCID, docId); - values.put(IndexColumns.LOCALE, locale); - values.put(IndexColumns.DATA_RANK, rank); - values.put(IndexColumns.DATA_TITLE, updatedTitle); - values.put(IndexColumns.DATA_TITLE_NORMALIZED, normalizedTitle); - values.put(IndexColumns.DATA_SUMMARY_ON, updatedSummaryOn); - values.put(IndexColumns.DATA_SUMMARY_ON_NORMALIZED, normalizedSummaryOn); - values.put(IndexColumns.DATA_SUMMARY_OFF, updatedSummaryOff); - values.put(IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, normalizedSummaryOff); - values.put(IndexColumns.DATA_ENTRIES, entries); - values.put(IndexColumns.DATA_KEYWORDS, spaceDelimitedKeywords); - values.put(IndexColumns.CLASS_NAME, className); - values.put(IndexColumns.SCREEN_TITLE, screenTitle); - values.put(IndexColumns.INTENT_ACTION, intentAction); - values.put(IndexColumns.INTENT_TARGET_PACKAGE, intentTargetPackage); - values.put(IndexColumns.INTENT_TARGET_CLASS, intentTargetClass); - values.put(IndexColumns.ICON, iconResId); - values.put(IndexColumns.ENABLED, enabled); - values.put(IndexColumns.DATA_KEY_REF, key); - values.put(IndexColumns.USER_ID, userId); - - database.replaceOrThrow(Tables.TABLE_PREFS_INDEX, null, values); - } - - private String getDataKey(Context context, AttributeSet attrs) { - return getData(context, attrs, - com.android.internal.R.styleable.Preference, - com.android.internal.R.styleable.Preference_key); - } - - private String getDataTitle(Context context, AttributeSet attrs) { - return getData(context, attrs, - com.android.internal.R.styleable.Preference, - com.android.internal.R.styleable.Preference_title); - } - - private String getDataSummary(Context context, AttributeSet attrs) { - return getData(context, attrs, - com.android.internal.R.styleable.Preference, - com.android.internal.R.styleable.Preference_summary); - } - - private String getDataSummaryOn(Context context, AttributeSet attrs) { - return getData(context, attrs, - com.android.internal.R.styleable.CheckBoxPreference, - com.android.internal.R.styleable.CheckBoxPreference_summaryOn); - } - - private String getDataSummaryOff(Context context, AttributeSet attrs) { - return getData(context, attrs, - com.android.internal.R.styleable.CheckBoxPreference, - com.android.internal.R.styleable.CheckBoxPreference_summaryOff); - } - - private String getDataEntries(Context context, AttributeSet attrs) { - return getDataEntries(context, attrs, - com.android.internal.R.styleable.ListPreference, - com.android.internal.R.styleable.ListPreference_entries); - } - - private String getDataKeywords(Context context, AttributeSet attrs) { - return getData(context, attrs, R.styleable.Preference, R.styleable.Preference_keywords); - } - - private String getData(Context context, AttributeSet set, int[] attrs, int resId) { - final TypedArray sa = context.obtainStyledAttributes(set, attrs); - final TypedValue tv = sa.peekValue(resId); - - CharSequence data = null; - if (tv != null && tv.type == TypedValue.TYPE_STRING) { - if (tv.resourceId != 0) { - data = context.getText(tv.resourceId); - } else { - data = tv.string; - } - } - return (data != null) ? data.toString() : null; - } - - private String getDataEntries(Context context, AttributeSet set, int[] attrs, int resId) { - final TypedArray sa = context.obtainStyledAttributes(set, attrs); - final TypedValue tv = sa.peekValue(resId); - - String[] data = null; - if (tv != null && tv.type == TypedValue.TYPE_REFERENCE) { - if (tv.resourceId != 0) { - data = context.getResources().getStringArray(tv.resourceId); - } - } - final int count = (data == null ) ? 0 : data.length; - if (count == 0) { - return null; - } - final StringBuilder result = new StringBuilder(); - for (int n = 0; n < count; n++) { - result.append(data[n]); - result.append(ENTRIES_SEPARATOR); - } - return result.toString(); - } - - /** - * A private class for updating the Index database - */ - private class UpdateIndexTask extends AsyncTask { - - @Override - protected void onPreExecute() { - super.onPreExecute(); - mIsAvailable.set(false); - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - mIsAvailable.set(true); - } - - @Override - protected Void doInBackground(UpdateData... params) { - try { - final List dataToUpdate = params[0].dataToUpdate; - final List dataToDelete = params[0].dataToDelete; - final Map> nonIndexableKeys = params[0].nonIndexableKeys; - - final boolean forceUpdate = params[0].forceUpdate; - final boolean fullIndex = params[0].fullIndex; - - final SQLiteDatabase database = getWritableDatabase(); - if (database == null) { - Log.e(LOG_TAG, "Cannot update Index as I cannot get a writable database"); - return null; - } - final String localeStr = Locale.getDefault().toString(); - - try { - database.beginTransaction(); - if (dataToDelete.size() > 0) { - processDataToDelete(database, localeStr, dataToDelete); - } - if (dataToUpdate.size() > 0) { - processDataToUpdate(database, localeStr, dataToUpdate, nonIndexableKeys, - forceUpdate); - } - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - if (fullIndex) { - IndexDatabaseHelper.setLocaleIndexed(mContext, localeStr); - } - } catch (SQLiteFullException e) { - Log.e(LOG_TAG, "Unable to index search, out of space", e); - } - - return null; - } - - private boolean processDataToUpdate(SQLiteDatabase database, String localeStr, - List dataToUpdate, Map> nonIndexableKeys, - boolean forceUpdate) { - - if (!forceUpdate && IndexDatabaseHelper.isLocaleAlreadyIndexed(mContext, localeStr)) { - Log.d(LOG_TAG, "Locale '" + localeStr + "' is already indexed"); - return true; - } - - boolean result = false; - final long current = System.currentTimeMillis(); - - final int count = dataToUpdate.size(); - for (int n = 0; n < count; n++) { - final SearchIndexableData data = dataToUpdate.get(n); - try { - indexOneSearchIndexableData(database, localeStr, data, nonIndexableKeys); - } catch (Exception e) { - Log.e(LOG_TAG, "Cannot index: " + (data != null ? data.className : data) - + " for locale: " + localeStr, e); - } - } - - final long now = System.currentTimeMillis(); - Log.d(LOG_TAG, "Indexing locale '" + localeStr + "' took " + - (now - current) + " millis"); - return result; - } - - private boolean processDataToDelete(SQLiteDatabase database, String localeStr, - List dataToDelete) { - - boolean result = false; - final long current = System.currentTimeMillis(); - - final int count = dataToDelete.size(); - for (int n = 0; n < count; n++) { - final SearchIndexableData data = dataToDelete.get(n); - if (data == null) { - continue; - } - if (!TextUtils.isEmpty(data.className)) { - delete(database, IndexColumns.CLASS_NAME, data.className); - } else { - if (data instanceof SearchIndexableRaw) { - final SearchIndexableRaw raw = (SearchIndexableRaw) data; - if (!TextUtils.isEmpty(raw.title)) { - delete(database, IndexColumns.DATA_TITLE, raw.title); - } - } - } - } - - final long now = System.currentTimeMillis(); - Log.d(LOG_TAG, "Deleting data for locale '" + localeStr + "' took " + - (now - current) + " millis"); - return result; - } - - private int delete(SQLiteDatabase database, String columName, String value) { - final String whereClause = columName + "=?"; - final String[] whereArgs = new String[] { value }; - - return database.delete(Tables.TABLE_PREFS_INDEX, whereClause, whereArgs); - } - } - - /** - * A basic AsyncTask for saving a Search query into the database - */ - private class SaveSearchQueryTask extends AsyncTask { - - @Override - protected Long doInBackground(String... params) { - final long now = new Date().getTime(); - - final ContentValues values = new ContentValues(); - values.put(IndexDatabaseHelper.SavedQueriesColumns.QUERY, params[0]); - values.put(IndexDatabaseHelper.SavedQueriesColumns.TIME_STAMP, now); - - final SQLiteDatabase database = getWritableDatabase(); - if (database == null) { - Log.e(LOG_TAG, "Cannot save Search queries as I cannot get a writable database"); - return -1L; - } - - long lastInsertedRowId = -1L; - try { - // First, delete all saved queries that are the same - database.delete(Tables.TABLE_SAVED_QUERIES, - IndexDatabaseHelper.SavedQueriesColumns.QUERY + " = ?", - new String[] { params[0] }); - - // Second, insert the saved query - lastInsertedRowId = - database.insertOrThrow(Tables.TABLE_SAVED_QUERIES, null, values); - - // Last, remove "old" saved queries - final long delta = lastInsertedRowId - MAX_SAVED_SEARCH_QUERY; - if (delta > 0) { - int count = database.delete(Tables.TABLE_SAVED_QUERIES, "rowId <= ?", - new String[] { Long.toString(delta) }); - Log.d(LOG_TAG, "Deleted '" + count + "' saved Search query(ies)"); - } - } catch (Exception e) { - Log.d(LOG_TAG, "Cannot update saved Search queries", e); - } - - return lastInsertedRowId; - } - } -} diff --git a/src/com/android/settings/search2/DatabaseIndexingManager.java b/src/com/android/settings/search2/DatabaseIndexingManager.java index 0b1d3393541..0d61a6658d1 100644 --- a/src/com/android/settings/search2/DatabaseIndexingManager.java +++ b/src/com/android/settings/search2/DatabaseIndexingManager.java @@ -120,6 +120,9 @@ import static com.android.settings.search2.DatabaseResultLoader.SELECT_COLUMNS; public class DatabaseIndexingManager { private static final String LOG_TAG = "DatabaseIndexingManager"; + public static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER = + "SEARCH_INDEX_DATA_PROVIDER"; + private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference"; private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference"; diff --git a/src/com/android/settings/search2/SearchFeatureProviderImpl.java b/src/com/android/settings/search2/SearchFeatureProviderImpl.java index cd9c470ecd0..b180c982679 100644 --- a/src/com/android/settings/search2/SearchFeatureProviderImpl.java +++ b/src/com/android/settings/search2/SearchFeatureProviderImpl.java @@ -26,7 +26,6 @@ import android.view.MenuItem; import com.android.settings.R; import com.android.settings.applications.PackageManagerWrapperImpl; import com.android.settings.dashboard.SiteMapManager; -import com.android.settings.search.Index; /** * FeatureProvider for the refactored search code. @@ -99,11 +98,7 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider { @Override public void updateIndex(Context context) { long indexStartTime = System.currentTimeMillis(); - if (isEnabled(context)) { - getIndexingManager(context).indexDatabase(); - } else { - Index.getInstance(context).update(); - } + getIndexingManager(context).indexDatabase(); Log.d(TAG, "IndexDatabase() took " + (System.currentTimeMillis() - indexStartTime) + " ms"); } diff --git a/src/com/android/settings/wifi/WifiEnabler.java b/src/com/android/settings/wifi/WifiEnabler.java index 1ac94ea25d9..87e4120f91d 100644 --- a/src/com/android/settings/wifi/WifiEnabler.java +++ b/src/com/android/settings/wifi/WifiEnabler.java @@ -24,8 +24,6 @@ import android.net.NetworkInfo; import android.net.wifi.SupplicantState; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; -import android.os.Handler; -import android.os.Message; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -34,7 +32,6 @@ import android.widget.Toast; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.core.instrumentation.MetricsFeatureProvider; -import com.android.settings.search.Index; import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; @@ -79,19 +76,6 @@ public class WifiEnabler implements SwitchWidgetController.OnSwitchChangeListene private static final String EVENT_DATA_IS_WIFI_ON = "is_wifi_on"; private static final int EVENT_UPDATE_INDEX = 0; - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_UPDATE_INDEX: - final boolean isWiFiOn = msg.getData().getBoolean(EVENT_DATA_IS_WIFI_ON); - Index.getInstance(mContext).updateFromClassNameResource( - WifiSettings.class.getName(), true, isWiFiOn); - break; - } - } - }; - public WifiEnabler(Context context, SwitchWidgetController switchWidget, MetricsFeatureProvider metricsFeatureProvider) { mContext = context; @@ -155,7 +139,6 @@ public class WifiEnabler implements SwitchWidgetController.OnSwitchChangeListene case WifiManager.WIFI_STATE_ENABLED: setSwitchBarChecked(true); mSwitchWidget.setEnabled(true); - updateSearchIndex(true); break; case WifiManager.WIFI_STATE_DISABLING: mSwitchWidget.setEnabled(false); @@ -163,12 +146,10 @@ public class WifiEnabler implements SwitchWidgetController.OnSwitchChangeListene case WifiManager.WIFI_STATE_DISABLED: setSwitchBarChecked(false); mSwitchWidget.setEnabled(true); - updateSearchIndex(false); break; default: setSwitchBarChecked(false); mSwitchWidget.setEnabled(true); - updateSearchIndex(false); } if (mayDisableTethering(!mSwitchWidget.isChecked())) { if (RestrictedLockUtils.hasBaseUserRestriction(mContext, @@ -182,15 +163,6 @@ public class WifiEnabler implements SwitchWidgetController.OnSwitchChangeListene } } - private void updateSearchIndex(boolean isWiFiOn) { - mHandler.removeMessages(EVENT_UPDATE_INDEX); - - Message msg = new Message(); - msg.what = EVENT_UPDATE_INDEX; - msg.getData().putBoolean(EVENT_DATA_IS_WIFI_ON, isWiFiOn); - mHandler.sendMessage(msg); - } - private void setSwitchBarChecked(boolean checked) { mStateMachineEvent = true; mSwitchWidget.setChecked(checked); diff --git a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java index 5455b13b183..c162aec0646 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/BuildNumberPreferenceControllerTest.java @@ -30,6 +30,7 @@ import com.android.settings.DevelopmentSettings; import com.android.settings.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; import com.android.settings.core.lifecycle.Lifecycle; +import com.android.settings.search2.DatabaseIndexingManager; import com.android.settings.testutils.FakeFeatureFactory; import org.junit.Before; @@ -172,7 +173,10 @@ public class BuildNumberPreferenceControllerTest { @Test public void onActivityResult_confirmPasswordRequestCompleted_enableDevPref() { - final Context context = ShadowApplication.getInstance().getApplicationContext(); + final Context context = RuntimeEnvironment.application; + + when(mFactory.searchFeatureProvider.getIndexingManager(any(Context.class))) + .thenReturn(mock(DatabaseIndexingManager.class)); mController = new BuildNumberPreferenceController( context, mActivity, mFragment, mLifecycle); diff --git a/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java b/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java index 0bd651aad35..5068349c42f 100644 --- a/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java +++ b/tests/robotests/src/com/android/settings/search/DynamicIndexableContentMonitorTest.java @@ -62,6 +62,7 @@ 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.search2.DatabaseIndexingManager; import com.android.settings.testutils.shadow.ShadowActivityWithLoadManager; import com.android.settings.testutils.shadow.ShadowContextImplWithRegisterReceiver; import com.android.settings.testutils.shadow.ShadowInputManager; @@ -72,6 +73,8 @@ 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; @@ -108,8 +111,10 @@ public class DynamicIndexableContentMonitorTest { private static final String IME_PACKAGE_1 = "ime-1"; private static final String IME_PACKAGE_2 = "ime-2"; - private LoaderManager mLoaderManager = mock(LoaderManager.class); - private Index mIndex = mock(Index.class); + @Mock + private LoaderManager mLoaderManager; + @Mock + private DatabaseIndexingManager mIndexManager; private Activity mActivity; private InputManager mInputManager; @@ -124,6 +129,7 @@ public class DynamicIndexableContentMonitorTest { @Before public void setUp() { + MockitoAnnotations.initMocks(this); mActivity = Robolectric.buildActivity(Activity.class).get(); mInputManager = InputManager.getInstance(); @@ -160,13 +166,13 @@ public class DynamicIndexableContentMonitorTest { @Test public void testLockedUser() { - mMonitor.register(mActivity, LOADER_ID, mIndex, false /* isUserUnlocked */); + 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(mIndex, never()).updateFromClassNameResource( + verify(mIndexManager, never()).updateFromClassNameResource( anyString(), anyBoolean(), anyBoolean()); mMonitor.unregister(mActivity, LOADER_ID); @@ -179,7 +185,7 @@ public class DynamicIndexableContentMonitorTest { public void testWithNoPrintingFeature() { mRobolectricPackageManager.setSystemFeature(PackageManager.FEATURE_PRINTING, false); - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); // No loader procedure happens. verify(mLoaderManager, never()).initLoader( @@ -194,12 +200,12 @@ public class DynamicIndexableContentMonitorTest { assertThat(extractPackageMonitor()).isNull(); // To suppress spurious test fail in {@link #shutDown()}. - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); } @Test public void testPrinterServiceIndex() { - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); // Loader procedure happens. verify(mLoaderManager, only()).initLoader(LOADER_ID, null, mMonitor); @@ -217,7 +223,7 @@ public class DynamicIndexableContentMonitorTest { @Test public void testInputDevicesMonitor() { - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); // Rebuild indexing should happen. verifyRebuildIndexing(PhysicalKeyboardFragment.class); @@ -229,9 +235,9 @@ public class DynamicIndexableContentMonitorTest { * Nothing happens on successive register calls. */ mMonitor.unregister(mActivity, LOADER_ID); - reset(mIndex); + reset(mIndexManager); - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); verifyNoIndexing(PhysicalKeyboardFragment.class); assertThat(extactInputDeviceListener()).isEqualTo(listener); @@ -239,7 +245,7 @@ public class DynamicIndexableContentMonitorTest { /* * A device is added. */ - reset(mIndex); + reset(mIndexManager); listener.onInputDeviceAdded(1 /* deviceId */); @@ -248,7 +254,7 @@ public class DynamicIndexableContentMonitorTest { /* * A device is removed. */ - reset(mIndex); + reset(mIndexManager); listener.onInputDeviceRemoved(2 /* deviceId */); @@ -257,7 +263,7 @@ public class DynamicIndexableContentMonitorTest { /* * A device is changed. */ - reset(mIndex); + reset(mIndexManager); listener.onInputDeviceChanged(3 /* deviceId */); @@ -266,14 +272,14 @@ public class DynamicIndexableContentMonitorTest { @Test public void testAccessibilityServicesMonitor() throws Exception { - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); verifyRebuildIndexing(AccessibilitySettings.class); /* * When an accessibility service package is installed, incremental indexing happen. */ - reset(mIndex); + reset(mIndexManager); installAccessibilityService(A11Y_PACKAGE_1); @@ -282,7 +288,7 @@ public class DynamicIndexableContentMonitorTest { /* * When another accessibility service package is installed, incremental indexing happens. */ - reset(mIndex); + reset(mIndexManager); installAccessibilityService(A11Y_PACKAGE_2); @@ -291,7 +297,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an accessibility service is disabled, rebuild indexing happens. */ - reset(mIndex); + reset(mIndexManager); disableInstalledPackage(A11Y_PACKAGE_1); @@ -300,7 +306,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an accessibility service is enabled, incremental indexing happens. */ - reset(mIndex); + reset(mIndexManager); enableInstalledPackage(A11Y_PACKAGE_1); @@ -309,7 +315,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an accessibility service package is uninstalled, rebuild indexing happens. */ - reset(mIndex); + reset(mIndexManager); uninstallAccessibilityService(A11Y_PACKAGE_1); @@ -318,7 +324,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an input method service package is installed, nothing happens. */ - reset(mIndex); + reset(mIndexManager); installInputMethodService(IME_PACKAGE_1); @@ -327,7 +333,7 @@ public class DynamicIndexableContentMonitorTest { @Test public void testInputMethodServicesMonitor() throws Exception { - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); verifyRebuildIndexing(VirtualKeyboardFragment.class); verifyRebuildIndexing(AvailableVirtualKeyboardFragment.class); @@ -341,7 +347,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an input method service package is installed, incremental indexing happen. */ - reset(mIndex); + reset(mIndexManager); installInputMethodService(IME_PACKAGE_1); @@ -351,7 +357,7 @@ public class DynamicIndexableContentMonitorTest { /* * When another input method service package is installed, incremental indexing happens. */ - reset(mIndex); + reset(mIndexManager); installInputMethodService(IME_PACKAGE_2); @@ -361,7 +367,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an input method service is disabled, rebuild indexing happens. */ - reset(mIndex); + reset(mIndexManager); disableInstalledPackage(IME_PACKAGE_1); @@ -371,7 +377,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an input method service is enabled, incremental indexing happens. */ - reset(mIndex); + reset(mIndexManager); enableInstalledPackage(IME_PACKAGE_1); @@ -381,7 +387,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an input method service package is uninstalled, rebuild indexing happens. */ - reset(mIndex); + reset(mIndexManager); uninstallInputMethodService(IME_PACKAGE_1); @@ -391,7 +397,7 @@ public class DynamicIndexableContentMonitorTest { /* * When an accessibility service package is installed, nothing happens. */ - reset(mIndex); + reset(mIndexManager); installAccessibilityService(A11Y_PACKAGE_1); @@ -401,7 +407,7 @@ public class DynamicIndexableContentMonitorTest { /* * When enabled IMEs list is changed, rebuild indexing happens. */ - reset(mIndex); + reset(mIndexManager); observer.onChange(false /* selfChange */, enabledInputMethodsContentUri); @@ -411,7 +417,7 @@ public class DynamicIndexableContentMonitorTest { @Test public void testUserDictionaryChangeMonitor() throws Exception { - mMonitor.register(mActivity, LOADER_ID, mIndex, true /* isUserUnlocked */); + mMonitor.register(mActivity, LOADER_ID, mIndexManager, true /* isUserUnlocked */); // Content observer should be registered. final ContentObserver observer = extractContentObserver(UserDictionary.Words.CONTENT_URI); @@ -422,7 +428,7 @@ public class DynamicIndexableContentMonitorTest { /* * When user dictionary content is changed, rebuild indexing happens. */ - reset(mIndex); + reset(mIndexManager); observer.onChange(false /* selfChange */, UserDictionary.Words.CONTENT_URI); @@ -434,21 +440,21 @@ public class DynamicIndexableContentMonitorTest { */ private void verifyNoIndexing(Class indexingClass) { - verify(mIndex, never()).updateFromClassNameResource(eq(indexingClass.getName()), + verify(mIndexManager, never()).updateFromClassNameResource(eq(indexingClass.getName()), anyBoolean(), anyBoolean()); } private void verifyRebuildIndexing(Class indexingClass) { - verify(mIndex, times(1)).updateFromClassNameResource(indexingClass.getName(), + verify(mIndexManager, times(1)).updateFromClassNameResource(indexingClass.getName(), true /* rebuild */, true /* includeInSearchResults */); - verify(mIndex, never()).updateFromClassNameResource(indexingClass.getName(), + verify(mIndexManager, never()).updateFromClassNameResource(indexingClass.getName(), false /* rebuild */, true /* includeInSearchResults */); } private void verifyIncrementalIndexing(Class indexingClass) { - verify(mIndex, times(1)).updateFromClassNameResource(indexingClass.getName(), + verify(mIndexManager, times(1)).updateFromClassNameResource(indexingClass.getName(), false /* rebuild */, true /* includeInSearchResults */); - verify(mIndex, never()).updateFromClassNameResource(indexingClass.getName(), + verify(mIndexManager, never()).updateFromClassNameResource(indexingClass.getName(), true /* rebuild */, true /* includeInSearchResults */); } diff --git a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java index c3147286dd4..63eeae071e2 100644 --- a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java @@ -88,13 +88,4 @@ public class SearchFeatureProviderImplTest { mProvider.updateIndex(mActivity); verify(mProvider).getIndexingManager(any(Context.class)); } - - @Test - public void testUpdateIndexNewSearch_UsesIndex() { - mProvider = spy(new SearchFeatureProviderImpl()); - when(mProvider.isEnabled(mActivity)).thenReturn(false); - - mProvider.updateIndex(mActivity); - verify(mProvider, never()).getIndexingManager(any(Context.class)); - } } diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java index 801b50964ff..972bca182ac 100644 --- a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java +++ b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java @@ -22,6 +22,7 @@ import android.util.Log; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.core.codeinspection.CodeInspector; import com.android.settings.dashboard.DashboardFragmentSearchIndexProviderInspector; +import com.android.settings.search2.DatabaseIndexingManager; import java.lang.reflect.Field; import java.util.ArrayList; @@ -39,14 +40,16 @@ public class SearchIndexProviderCodeInspector extends CodeInspector { private static final String NOT_IMPLEMENTING_INDEXABLE_ERROR = "SettingsPreferenceFragment should implement Indexable, but these do not:\n"; private static final String NOT_CONTAINING_PROVIDER_OBJECT_ERROR = - "Indexable should have public field " + Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "Indexable should have public field " + + DatabaseIndexingManager.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + " but these are not:\n"; private static final String NOT_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER = "DashboardFragment should share pref controllers with its SearchIndexProvider, but " + " these are not: \n"; private static final String NOT_IN_INDEXABLE_PROVIDER_REGISTRY = - "Class containing " + Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + " must be added to " - + SearchIndexableResources.class.getName() + " but these are not: \n"; + "Class containing " + DatabaseIndexingManager.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + + " must be added to " + SearchIndexableResources.class.getName() + + " but these are not: \n"; private final List notImplementingIndexableGrandfatherList; private final List notImplementingIndexProviderGrandfatherList; @@ -146,7 +149,8 @@ public class SearchIndexProviderCodeInspector extends CodeInspector { private boolean hasSearchIndexProvider(Class clazz) { try { - final Field f = clazz.getField(Index.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); + final Field f = clazz.getField( + DatabaseIndexingManager.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); return f != null; } catch (NoClassDefFoundError e) { // Cannot find class def, ignore