Reindex db when package w/ searchIndexProvider changes

We do this by tracking a list of package/version that provides search
indexing data. When they change, we do a full reindex.

Change-Id: I85d4c4a994c7ff808662371c857cac1929a8b1cd
Merged-In: I906a1524f5b1292932f63727d605283ddb7d6ee2
Bug: 63903835
Test: robotests
This commit is contained in:
Fan Zhang
2017-07-20 17:05:01 -07:00
parent e4c9b7162d
commit b4c40e5dea
4 changed files with 143 additions and 73 deletions

View File

@@ -166,18 +166,22 @@ public class DatabaseIndexingManager {
*/
public void performIndexing() {
final Intent intent = new Intent(SearchIndexablesContract.PROVIDER_INTERFACE);
final List<ResolveInfo> list =
final List<ResolveInfo> providers =
mContext.getPackageManager().queryIntentContentProviders(intent, 0);
String localeStr = Locale.getDefault().toString();
String fingerprint = Build.FINGERPRINT;
final boolean isFullIndex = isFullIndex(localeStr, fingerprint);
final String localeStr = Locale.getDefault().toString();
final String fingerprint = Build.FINGERPRINT;
final String providerVersionedNames =
IndexDatabaseHelper.buildProviderVersionedNames(providers);
final boolean isFullIndex = IndexDatabaseHelper.isFullIndex(mContext, localeStr,
fingerprint, providerVersionedNames);
if (isFullIndex) {
rebuildDatabase();
}
for (final ResolveInfo info : list) {
for (final ResolveInfo info : providers) {
if (!DatabaseIndexingUtils.isWellKnownProvider(info, mContext)) {
continue;
}
@@ -192,24 +196,10 @@ public class DatabaseIndexingManager {
updateDatabase(isFullIndex, localeStr);
//TODO(63922686): Setting indexed should be a single method, not 3 separate setters.
IndexDatabaseHelper.setLocaleIndexed(mContext, localeStr);
IndexDatabaseHelper.setBuildIndexed(mContext, fingerprint);
}
/**
* Perform a full index on an OTA or when the locale has changed
*
* @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.
*/
@VisibleForTesting
boolean isFullIndex(String locale, String fingerprint) {
final boolean isLocaleIndexed = IndexDatabaseHelper.getInstance(mContext)
.isLocaleAlreadyIndexed(mContext, locale);
final boolean isBuildIndexed = IndexDatabaseHelper.getInstance(mContext)
.isBuildIndexed(mContext, fingerprint);
return !isLocaleIndexed || !isBuildIndexed;
IndexDatabaseHelper.setProvidersIndexed(mContext, providerVersionedNames);
}
/**
@@ -1318,4 +1308,4 @@ public class DatabaseIndexingManager {
}
}
}
}
}

View File

@@ -174,7 +174,7 @@ public class DatabaseIndexingUtils {
* - have read/write {@link Manifest.permission#READ_SEARCH_INDEXABLES}
* - be from a privileged package
*/
public static boolean isWellKnownProvider(ResolveInfo info, Context context) {
static boolean isWellKnownProvider(ResolveInfo info, Context context) {
final String authority = info.providerInfo.authority;
final String packageName = info.providerInfo.applicationInfo.packageName;
@@ -197,7 +197,22 @@ public class DatabaseIndexingUtils {
return isPrivilegedPackage(packageName, context);
}
public static boolean isPrivilegedPackage(String packageName, Context context) {
static String normalizeHyphen(String input) {
return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY;
}
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();
}
static String normalizeKeywords(String input) {
return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY;
}
private static boolean isPrivilegedPackage(String packageName, Context context) {
final PackageManager pm = context.getPackageManager();
try {
PackageInfo packInfo = pm.getPackageInfo(packageName, 0);
@@ -207,19 +222,4 @@ public class DatabaseIndexingUtils {
return false;
}
}
public static String normalizeHyphen(String input) {
return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY;
}
public 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();
}
public static String normalizeKeywords(String input) {
return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY;
}
}

View File

@@ -17,12 +17,17 @@
package com.android.settings.search;
import android.content.Context;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.Log;
import java.util.List;
public class IndexDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "IndexDatabaseHelper";
@@ -32,6 +37,8 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper {
private static final String INDEX = "index";
private static final String PREF_KEY_INDEXED_PROVIDERS = "indexed_providers";
public interface Tables {
String TABLE_PREFS_INDEX = "prefs_index";
String TABLE_SITE_MAP = "site_map";
@@ -245,23 +252,69 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper {
return version;
}
public static void clearCachedIndexed(Context context) {
context.getSharedPreferences(INDEX, 0).edit().clear().commit();
/**
* Perform a full index on an OTA or when the locale has changed
*
* @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.
*/
@VisibleForTesting
static boolean isFullIndex(Context context, String locale, String fingerprint,
String providerVersionedNames) {
final boolean isLocaleIndexed = IndexDatabaseHelper.isLocaleAlreadyIndexed(context, locale);
final boolean isBuildIndexed = IndexDatabaseHelper.isBuildIndexed(context, fingerprint);
final boolean areProvidersIndexed = IndexDatabaseHelper
.areProvidersIndexed(context, providerVersionedNames);
return !(isLocaleIndexed && isBuildIndexed && areProvidersIndexed);
}
public static void setLocaleIndexed(Context context, String locale) {
context.getSharedPreferences(INDEX, 0).edit().putBoolean(locale, true).commit();
@VisibleForTesting
static String buildProviderVersionedNames(List<ResolveInfo> providers) {
StringBuilder sb = new StringBuilder();
for (ResolveInfo info : providers) {
sb.append(info.providerInfo.packageName)
.append(':')
.append(info.providerInfo.applicationInfo.versionCode)
.append(',');
}
return sb.toString();
}
public static boolean isLocaleAlreadyIndexed(Context context, String locale) {
return context.getSharedPreferences(INDEX, 0).getBoolean(locale, false);
static void clearCachedIndexed(Context context) {
context.getSharedPreferences(INDEX, Context.MODE_PRIVATE).edit().clear().commit();
}
public static boolean isBuildIndexed(Context context, String buildNo) {
return context.getSharedPreferences(INDEX, 0).getBoolean(buildNo, false);
static void setLocaleIndexed(Context context, String locale) {
context.getSharedPreferences(INDEX, Context.MODE_PRIVATE)
.edit()
.putBoolean(locale, true)
.apply();
}
public static void setBuildIndexed(Context context, String buildNo) {
static void setProvidersIndexed(Context context, String providerVersionedNames) {
context.getSharedPreferences(INDEX, Context.MODE_PRIVATE)
.edit()
.putString(PREF_KEY_INDEXED_PROVIDERS, providerVersionedNames)
.apply();
}
static boolean isLocaleAlreadyIndexed(Context context, String locale) {
return context.getSharedPreferences(INDEX, Context.MODE_PRIVATE).getBoolean(locale, false);
}
static boolean areProvidersIndexed(Context context, String providerVersionedNames) {
final String indexedProviders = context.getSharedPreferences(INDEX, Context.MODE_PRIVATE)
.getString(PREF_KEY_INDEXED_PROVIDERS, null);
return TextUtils.equals(indexedProviders, providerVersionedNames);
}
static boolean isBuildIndexed(Context context, String buildNo) {
return context.getSharedPreferences(INDEX, Context.MODE_PRIVATE).getBoolean(buildNo, false);
}
static void setBuildIndexed(Context context, String buildNo) {
context.getSharedPreferences(INDEX, 0).edit().putBoolean(buildNo, true).commit();
}