Merge "Improve search indexing time."

This commit is contained in:
TreeHugger Robot
2017-07-18 23:33:28 +00:00
committed by Android (Google) Code Review
11 changed files with 140 additions and 99 deletions

View File

@@ -39,10 +39,7 @@ public class UserDictionaryPreferenceController extends AbstractPreferenceContro
@Override
public boolean isAvailable() {
final TreeSet<String> localeSet = getDictionaryLocales();
// The locale list is null if and only if the user dictionary service is
// not present or disabled. In this case we need to remove the preference.
return localeSet != null;
return true;
}
@Override

View File

@@ -31,7 +31,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.Indexable;
public class ZenModePrioritySettings extends ZenModeSettingsBase implements Indexable {
public class ZenModePrioritySettings extends ZenModeSettingsBase {
private static final String KEY_REMINDERS = "reminders";
private static final String KEY_EVENTS = "events";
private static final String KEY_MESSAGES = "messages";

View File

@@ -17,53 +17,6 @@
package com.android.settings.search;
import com.android.settings.R;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.provider.SearchIndexableData;
import android.provider.SearchIndexableResource;
import android.provider.SearchIndexablesContract;
import android.support.annotation.DrawableRes;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.util.Xml;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.SettingsActivity;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
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;
@@ -85,17 +38,22 @@ import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INT
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_RESID;
import static com.android.settings.search.DatabaseResultLoader.*;
import static com.android.settings.search.DatabaseResultLoader.COLUMN_INDEX_ID;
import static com.android.settings.search.DatabaseResultLoader
.COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE;
import static com.android.settings.search.DatabaseResultLoader.COLUMN_INDEX_KEY;
import static com.android.settings.search.DatabaseResultLoader.SELECT_COLUMNS;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.CLASS_NAME;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_ENTRIES;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEY_REF;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_RANK;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns
.DATA_SUMMARY_OFF_NORMALIZED;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns
.DATA_SUMMARY_ON_NORMALIZED;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED;
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DOCID;
@@ -111,6 +69,49 @@ import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.SCREE
import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.USER_ID;
import static com.android.settings.search.IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.provider.SearchIndexableData;
import android.provider.SearchIndexableResource;
import android.provider.SearchIndexablesContract;
import android.support.annotation.DrawableRes;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import com.android.settings.SettingsActivity;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Consumes the SearchIndexableProvider content providers.
* Updates the Resource, Raw Data and non-indexable data for Search.
@@ -118,6 +119,7 @@ import static com.android.settings.search.IndexDatabaseHelper.Tables.TABLE_PREFS
* TODO this class needs to be refactored by moving most of its methods into controllers
*/
public class DatabaseIndexingManager {
private static final String LOG_TAG = "DatabaseIndexingManager";
private static final String METRICS_ACTION_SETTINGS_ASYNC_INDEX =
@@ -165,6 +167,7 @@ public class DatabaseIndexingManager {
* calls will only gather non-indexable keys.
*/
public void performIndexing() {
final long startTime = System.currentTimeMillis();
final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE);
final List<ResolveInfo> list =
mContext.getPackageManager().queryIntentContentProviders(intent, 0);
@@ -187,19 +190,34 @@ public class DatabaseIndexingManager {
if (isFullIndex) {
addIndexablesFromRemoteProvider(packageName, authority);
}
final long nonIndexableStartTime = System.currentTimeMillis();
addNonIndexablesKeysFromRemoteProvider(packageName, authority);
if (SettingsSearchIndexablesProvider.DEBUG) {
final long nonIndextableTime = System.currentTimeMillis() - nonIndexableStartTime;
Log.d(LOG_TAG, "performIndexing update non-indexable for package " + packageName
+ " took time: " + nonIndextableTime);
}
}
final long updateDatabaseStartTime = System.currentTimeMillis();
updateDatabase(isFullIndex, localeStr);
if (SettingsSearchIndexablesProvider.DEBUG) {
final long updateDatabaseTime = System.currentTimeMillis() - updateDatabaseStartTime;
Log.d(LOG_TAG, "performIndexing updateDatabase took time: " + updateDatabaseTime);
}
IndexDatabaseHelper.setLocaleIndexed(mContext, localeStr);
IndexDatabaseHelper.setBuildIndexed(mContext, fingerprint);
if (SettingsSearchIndexablesProvider.DEBUG) {
final long indexingTime = System.currentTimeMillis() - startTime;
Log.d(LOG_TAG, "performIndexing took time: " + indexingTime
+ "ms. Full index? " + isFullIndex);
}
}
/**
* Perform a full index on an OTA or when the locale has changed
*
* @param locale is the default for the device
* @param locale is the default for the device
* @param fingerprint id for the current build.
* @return true when the locale or build has changed since last index.
*/
@@ -232,7 +250,7 @@ public class DatabaseIndexingManager {
* Finally, we record that the locale has been indexed.
*
* @param needsReindexing true the database needs to be rebuilt.
* @param localeStr the default locale for the device.
* @param localeStr the default locale for the device.
*/
@VisibleForTesting
void updateDatabase(boolean needsReindexing, String localeStr) {
@@ -275,9 +293,9 @@ public class DatabaseIndexingManager {
/**
* Inserts {@link SearchIndexableData} into the database.
*
* @param database where the data will be inserted.
* @param localeStr is the locale of the data to be inserted.
* @param dataToUpdate is a {@link List} of the data to be inserted.
* @param database where the data will be inserted.
* @param localeStr is the locale of the data to be inserted.
* @param dataToUpdate is a {@link List} of the data to be inserted.
* @param nonIndexableKeys is a {@link Map} from Package Name to a {@link Set} of keys which
* identify search results which should not be surfaced.
*/
@@ -305,7 +323,7 @@ public class DatabaseIndexingManager {
* All rows which are enabled but are now flagged with non-indexable keys will become disabled.
* All rows which are disabled but no longer a non-indexable key will become enabled.
*
* @param database The database to validate.
* @param database The database to validate.
* @param nonIndexableKeys A map between package name and the set of non-indexable keys for it.
*/
@VisibleForTesting
@@ -395,7 +413,8 @@ public class DatabaseIndexingManager {
String authority) {
final List<String> keys =
getNonIndexablesKeysFromRemoteProvider(packageName, authority);
addNonIndexableKeys(packageName, new HashSet<>(keys));
addNonIndexableKeys(packageName, keys);
}
private List<String> getNonIndexablesKeysFromRemoteProvider(String packageName,
@@ -452,9 +471,11 @@ public class DatabaseIndexingManager {
}
}
public void addNonIndexableKeys(String authority, Set<String> keys) {
public void addNonIndexableKeys(String authority, List<String> keys) {
synchronized (mDataToProcess) {
mDataToProcess.nonIndexableKeys.put(authority, keys);
if (keys != null && !keys.isEmpty()) {
mDataToProcess.nonIndexableKeys.put(authority, new ArraySet<>(keys));
}
}
}
@@ -787,7 +808,7 @@ public class DatabaseIndexingManager {
title = XmlParserUtils.getDataTitle(context, attrs);
key = XmlParserUtils.getDataKey(context, attrs);
enabled = ! nonIndexableKeys.contains(key);
enabled = !nonIndexableKeys.contains(key);
keywords = XmlParserUtils.getDataKeywords(context, attrs);
iconResId = XmlParserUtils.getDataIcon(context, attrs);

View File

@@ -21,6 +21,7 @@ import android.app.LoaderManager;
import android.content.Context;
import android.content.Loader;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -38,6 +39,7 @@ public class SavedQueryController implements LoaderManager.LoaderCallbacks,
private static final int LOADER_ID_REMOVE_QUERY_TASK = 1;
private static final int LOADER_ID_SAVED_QUERIES = 2;
private static final String ARG_QUERY = "remove_query";
private static final String TAG = "SearchSavedQueryCtrl";
private static final int MENU_SEARCH_HISTORY = 1000;
@@ -75,6 +77,9 @@ public class SavedQueryController implements LoaderManager.LoaderCallbacks,
mLoaderManager.restartLoader(LOADER_ID_SAVED_QUERIES, null, this);
break;
case LOADER_ID_SAVED_QUERIES:
if (SettingsSearchIndexablesProvider.DEBUG) {
Log.d(TAG, "Saved queries loaded");
}
mResultAdapter.displaySavedQuery((List<SearchResult>) data);
break;
}
@@ -114,6 +119,9 @@ public class SavedQueryController implements LoaderManager.LoaderCallbacks,
}
public void loadSavedQueries() {
if (SettingsSearchIndexablesProvider.DEBUG) {
Log.d(TAG, "loading saved queries");
}
mLoaderManager.restartLoader(LOADER_ID_SAVED_QUERIES, null, this);
}
}

View File

@@ -16,16 +16,12 @@
*/
package com.android.settings.search;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import com.android.settings.dashboard.SiteMapManager;
import com.android.settings.search.ranking.SearchResultsRankerCallback;
import java.util.List;
/**
* FeatureProvider for Settings Search
*/

View File

@@ -19,6 +19,8 @@ package com.android.settings.search;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import com.android.settings.applications.PackageManagerWrapperImpl;
import com.android.settings.dashboard.SiteMapManager;
import com.android.settings.overlay.FeatureFactory;
@@ -80,6 +82,9 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider {
@Override
public void updateIndexAsync(Context context, IndexingCallback callback) {
if (SettingsSearchIndexablesProvider.DEBUG) {
Log.d(TAG, "updating index async");
}
getIndexingManager(context).indexDatabase(callback);
}

View File

@@ -140,6 +140,7 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
long startTime = System.currentTimeMillis();
setHasOptionsMenu(true);
final LoaderManager loaderManager = getLoaderManager();
@@ -164,6 +165,9 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
} else {
Log.w(TAG, "Cannot update the Indexer as we are running low on storage space!");
}
if (SettingsSearchIndexablesProvider.DEBUG) {
Log.d(TAG, "onCreate spent " + (System.currentTimeMillis() - startTime) + " ms");
}
}
@Override

View File

@@ -16,18 +16,6 @@
package com.android.settings.search;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.provider.SearchIndexableResource;
import android.provider.SearchIndexablesProvider;
import android.util.Log;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID;
@@ -40,9 +28,30 @@ import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS;
import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS;
import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.provider.SearchIndexableResource;
import android.provider.SearchIndexablesProvider;
import android.util.ArraySet;
import android.util.Log;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
public static final boolean DEBUG = false;
private static final String TAG = "SettingsSearchProvider";
private static final Collection<String> INVALID_KEYS;
static {
INVALID_KEYS = new ArraySet<>();
INVALID_KEYS.add(null);
INVALID_KEYS.add("");
}
@Override
public boolean onCreate() {
return true;
@@ -84,6 +93,10 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
final Context context = getContext();
for (SearchIndexableResource sir : SearchIndexableResources.values()) {
if (DEBUG) {
Log.d(TAG, "Getting non-indexable from " + sir.className);
}
final long startTime = System.currentTimeMillis();
final Class<?> clazz = DatabaseIndexingUtils.getIndexableClass(sir.className);
if (clazz == null) {
Log.d(TAG, "SearchIndexableResource '" + sir.className +
@@ -95,22 +108,28 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
DatabaseIndexingUtils.getSearchIndexProvider(clazz);
if (provider == null) {
Log.d(TAG, "Unable to get SearchIndexableProvider from " +
Indexable.class.getName());
Log.d(TAG, "Unable to get SearchIndexableProvider from " + clazz);
continue;
}
List<String> providerNonIndexableKeys = provider.getNonIndexableKeys(context);
if (providerNonIndexableKeys == null || providerNonIndexableKeys.isEmpty()) {
if (DEBUG) {
final long totalTime = System.currentTimeMillis() - startTime;
Log.d(TAG, "No indexable, total time " + totalTime);
}
continue;
}
if (providerNonIndexableKeys.removeAll(Collections.singleton(null))
|| providerNonIndexableKeys.removeAll(Collections.singleton(""))) {
if (providerNonIndexableKeys.removeAll(INVALID_KEYS)) {
Log.v(TAG, clazz.getName() + " tried to add an empty non-indexable key");
}
if (DEBUG) {
final long totalTime = System.currentTimeMillis() - startTime;
Log.d(TAG, "Non-indexables " + providerNonIndexableKeys.size() + ", total time "
+ totalTime);
}
values.addAll(providerNonIndexableKeys);
}

View File

@@ -1,7 +1,6 @@
com.android.settings.bluetooth.DevicePickerFragment
com.android.settings.bluetooth.BluetoothDeviceDetailsFragment
com.android.settings.bluetooth.BluetoothPairingDetail
com.android.settings.notification.ZenModePrioritySettings
com.android.settings.accounts.AccountDetailDashboardFragment
com.android.settings.fuelgauge.PowerUsageAnomalyDetails
com.android.settings.fuelgauge.AdvancedPowerUsageDetail

View File

@@ -1,4 +1,5 @@
com.android.settings.location.LocationMode
com.android.settings.notification.ZenModePrioritySettings
com.android.settings.notification.ZenModeVisualInterruptionSettings
com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragment
com.android.settings.deviceinfo.SimStatus

View File

@@ -56,16 +56,7 @@ public class UserDictionaryPreferenceControllerTest {
}
@Test
public void testIsAvailable_noLocale_shouldReturnFalse() {
mController.mLocales = null;
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void testIsAvailable_hasLocale_shouldReturnTrue() {
mController.mLocales.add("en");
public void testIsAvailable_shouldReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}