Loading apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java +14 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,9 @@ public final class SearchResult { /** @hide */ public static final String PACKAGE_NAME_FIELD = "packageName"; /** @hide */ public static final String DATABASE_NAME_FIELD = "databaseName"; @NonNull private final Bundle mBundle; /** Cache of the inflated document. Comes from inflating mDocumentBundle at first use. */ Loading Loading @@ -118,6 +121,17 @@ public final class SearchResult { return Preconditions.checkNotNull(mBundle.getString(PACKAGE_NAME_FIELD)); } /** * Contains the database name that stored the {@link GenericDocument}. * * @return Database name that stored the document * @hide */ @NonNull public String getDatabaseName() { return Preconditions.checkNotNull(mBundle.getString(DATABASE_NAME_FIELD)); } /** * This class represents a match objects for any Snippets that might be present in {@link * SearchResults} from query. Using this class user can get the full text, exact matches and Loading apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +38 −8 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.GetAllNamespacesResultProto; import com.google.android.icing.proto.GetOptimizeInfoResultProto; import com.google.android.icing.proto.GetResultProto; import com.google.android.icing.proto.GetResultSpecProto; import com.google.android.icing.proto.GetSchemaResultProto; import com.google.android.icing.proto.IcingSearchEngineOptions; import com.google.android.icing.proto.InitializeResultProto; Loading @@ -62,6 +63,7 @@ import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; import com.google.android.icing.proto.SetSchemaResultProto; import com.google.android.icing.proto.StatusProto; import com.google.android.icing.proto.TypePropertyMask; import java.io.File; import java.util.ArrayList; Loading Loading @@ -432,7 +434,9 @@ public final class AppSearchImpl { try { getResultProto = mIcingSearchEngineLocked.get( createPrefix(packageName, databaseName) + namespace, uri); createPrefix(packageName, databaseName) + namespace, uri, GetResultSpecProto.getDefaultInstance()); } finally { mReadWriteLock.readLock().unlock(); } Loading Loading @@ -691,8 +695,6 @@ public final class AppSearchImpl { * <p>If the app crashes before a call to PersistToDisk(), Icing would trigger a costly recovery * process in next initialization. After that, Icing would still be able to recover all written * data. * * @throws AppSearchException */ public void persistToDisk() throws AppSearchException { PersistToDiskResultProto persistToDiskResultProto = Loading Loading @@ -986,13 +988,12 @@ public final class AppSearchImpl { return false; } List<ResultSpecProto.TypePropertyMask> prefixedTypePropertyMasks = new ArrayList<>(); List<TypePropertyMask> prefixedTypePropertyMasks = new ArrayList<>(); // Rewrite filters to include a database prefix. for (String prefix : existingPrefixes) { Set<String> existingSchemaTypes = mSchemaMapLocked.get(prefix); // Qualify the given schema types for (ResultSpecProto.TypePropertyMask typePropertyMask : resultSpecBuilder.getTypePropertyMasksList()) { for (TypePropertyMask typePropertyMask : resultSpecBuilder.getTypePropertyMasksList()) { String qualifiedType = prefix + typePropertyMask.getSchemaType(); if (existingSchemaTypes.contains(qualifiedType)) { prefixedTypePropertyMasks.add( Loading Loading @@ -1060,12 +1061,36 @@ public final class AppSearchImpl { int delimiterIndex = prefix.indexOf(PACKAGE_DELIMITER); if (delimiterIndex == -1) { // This should never happen if we construct our prefixes properly Log.wtf(TAG, "Malformed prefix doesn't contain package name: " + prefix); Log.wtf(TAG, "Malformed prefix doesn't contain package delimiter: " + prefix); return ""; } return prefix.substring(0, delimiterIndex); } /** * Returns the database name that's contained within the {@code prefix}. * * @param prefix Prefix string that contains the database name inside of it. The database name * must be between the {@link #PACKAGE_DELIMITER} and {@link #DATABASE_DELIMITER} * @return Valid database name. */ @NonNull private static String getDatabaseName(@NonNull String prefix) { int packageDelimiterIndex = prefix.indexOf(PACKAGE_DELIMITER); int databaseDelimiterIndex = prefix.indexOf(DATABASE_DELIMITER); if (packageDelimiterIndex == -1) { // This should never happen if we construct our prefixes properly Log.wtf(TAG, "Malformed prefix doesn't contain package delimiter: " + prefix); return ""; } if (databaseDelimiterIndex == -1) { // This should never happen if we construct our prefixes properly Log.wtf(TAG, "Malformed prefix doesn't contain database delimiter: " + prefix); return ""; } return prefix.substring(packageDelimiterIndex + 1, databaseDelimiterIndex); } @NonNull private static String removePrefix(@NonNull String prefixedString) throws AppSearchException { // The prefix is made up of the package, then the database. So we only need to find the Loading Loading @@ -1178,6 +1203,9 @@ public final class AppSearchImpl { // Parallel array of package names for each document search result. List<String> packageNames = new ArrayList<>(searchResultProto.getResultsCount()); // Parallel array of database names for each document search result. List<String> databaseNames = new ArrayList<>(searchResultProto.getResultsCount()); SearchResultProto.Builder resultsBuilder = searchResultProto.toBuilder(); for (int i = 0; i < searchResultProto.getResultsCount(); i++) { SearchResultProto.ResultProto.Builder resultBuilder = Loading @@ -1185,10 +1213,12 @@ public final class AppSearchImpl { DocumentProto.Builder documentBuilder = resultBuilder.getDocument().toBuilder(); String prefix = removePrefixesFromDocument(documentBuilder); packageNames.add(getPackageName(prefix)); databaseNames.add(getDatabaseName(prefix)); resultBuilder.setDocument(documentBuilder); resultsBuilder.setResults(i, resultBuilder); } return SearchResultToProtoConverter.toSearchResultPage(resultsBuilder, packageNames); return SearchResultToProtoConverter.toSearchResultPage( resultsBuilder, packageNames, databaseNames); } @GuardedBy("mReadWriteLock") Loading apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java +14 −3 Original line number Diff line number Diff line Loading @@ -46,11 +46,16 @@ public class SearchResultToProtoConverter { * @param proto The {@link SearchResultProto} containing results. * @param packageNames A parallel array of package names. The package name at index 'i' of this * list should be the package that indexed the document at index 'i' of proto.getResults(i). * @param databaseNames A parallel array of database names. The database name at index 'i' of * this list shold be the database that indexed the document at index 'i' of * proto.getResults(i). * @return {@link SearchResultPage} of results. */ @NonNull public static SearchResultPage toSearchResultPage( @NonNull SearchResultProtoOrBuilder proto, @NonNull List<String> packageNames) { @NonNull SearchResultProtoOrBuilder proto, @NonNull List<String> packageNames, @NonNull List<String> databaseNames) { Preconditions.checkArgument( proto.getResultsCount() == packageNames.size(), "Size of " + "results does not match the number of package names."); Loading @@ -58,7 +63,9 @@ public class SearchResultToProtoConverter { bundle.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, proto.getNextPageToken()); ArrayList<Bundle> resultBundles = new ArrayList<>(proto.getResultsCount()); for (int i = 0; i < proto.getResultsCount(); i++) { resultBundles.add(toSearchResultBundle(proto.getResults(i), packageNames.get(i))); resultBundles.add( toSearchResultBundle( proto.getResults(i), packageNames.get(i), databaseNames.get(i))); } bundle.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles); return new SearchResultPage(bundle); Loading @@ -69,16 +76,20 @@ public class SearchResultToProtoConverter { * * @param proto The proto to be converted. * @param packageName The package name associated with the document in {@code proto}. * @param databaseName The database name associated with the document in {@code proto}. * @return A {@link SearchResult} bundle. */ @NonNull private static Bundle toSearchResultBundle( @NonNull SearchResultProto.ResultProtoOrBuilder proto, @NonNull String packageName) { @NonNull SearchResultProto.ResultProtoOrBuilder proto, @NonNull String packageName, @NonNull String databaseName) { Bundle bundle = new Bundle(); GenericDocument document = GenericDocumentToProtoConverter.toGenericDocument(proto.getDocument()); bundle.putBundle(SearchResult.DOCUMENT_FIELD, document.getBundle()); bundle.putString(SearchResult.PACKAGE_NAME_FIELD, packageName); bundle.putString(SearchResult.DATABASE_NAME_FIELD, databaseName); ArrayList<Bundle> matchList = new ArrayList<>(); if (proto.hasSnippet()) { Loading apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java +3 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import com.google.android.icing.proto.ResultSpecProto; import com.google.android.icing.proto.ScoringSpecProto; import com.google.android.icing.proto.SearchSpecProto; import com.google.android.icing.proto.TermMatchType; import com.google.android.icing.proto.TypePropertyMask; import java.util.List; import java.util.Map; Loading Loading @@ -71,7 +72,7 @@ public final class SearchSpecToProtoConverter { Map<String, List<String>> projectionTypePropertyPaths = spec.getProjections(); for (Map.Entry<String, List<String>> e : projectionTypePropertyPaths.entrySet()) { builder.addTypePropertyMasks( ResultSpecProto.TypePropertyMask.newBuilder() TypePropertyMask.newBuilder() .setSchemaType(e.getKey()) .addAllPaths(e.getValue())); } Loading Loading @@ -107,8 +108,7 @@ public final class SearchSpecToProtoConverter { case SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP: return ScoringSpecProto.RankingStrategy.Code.CREATION_TIMESTAMP; case SearchSpec.RANKING_STRATEGY_RELEVANCE_SCORE: return ScoringSpecProto.RankingStrategy.Code .RELEVANCE_SCORE_NONFUNCTIONAL_PLACEHOLDER; return ScoringSpecProto.RankingStrategy.Code.RELEVANCE_SCORE; default: throw new IllegalArgumentException( "Invalid result ranking strategy: " + rankingStrategyCode); Loading apex/appsearch/synced_jetpack_changeid.txt +1 −1 Original line number Diff line number Diff line I6745091e5cb97d69ce2e5f85d3d15c073e7e3ef7 Icd58005ad659b6b3d03f683f8954939175324685 Loading
apex/appsearch/framework/java/external/android/app/appsearch/SearchResult.java +14 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,9 @@ public final class SearchResult { /** @hide */ public static final String PACKAGE_NAME_FIELD = "packageName"; /** @hide */ public static final String DATABASE_NAME_FIELD = "databaseName"; @NonNull private final Bundle mBundle; /** Cache of the inflated document. Comes from inflating mDocumentBundle at first use. */ Loading Loading @@ -118,6 +121,17 @@ public final class SearchResult { return Preconditions.checkNotNull(mBundle.getString(PACKAGE_NAME_FIELD)); } /** * Contains the database name that stored the {@link GenericDocument}. * * @return Database name that stored the document * @hide */ @NonNull public String getDatabaseName() { return Preconditions.checkNotNull(mBundle.getString(DATABASE_NAME_FIELD)); } /** * This class represents a match objects for any Snippets that might be present in {@link * SearchResults} from query. Using this class user can get the full text, exact matches and Loading
apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchImpl.java +38 −8 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import com.google.android.icing.proto.DocumentProto; import com.google.android.icing.proto.GetAllNamespacesResultProto; import com.google.android.icing.proto.GetOptimizeInfoResultProto; import com.google.android.icing.proto.GetResultProto; import com.google.android.icing.proto.GetResultSpecProto; import com.google.android.icing.proto.GetSchemaResultProto; import com.google.android.icing.proto.IcingSearchEngineOptions; import com.google.android.icing.proto.InitializeResultProto; Loading @@ -62,6 +63,7 @@ import com.google.android.icing.proto.SearchResultProto; import com.google.android.icing.proto.SearchSpecProto; import com.google.android.icing.proto.SetSchemaResultProto; import com.google.android.icing.proto.StatusProto; import com.google.android.icing.proto.TypePropertyMask; import java.io.File; import java.util.ArrayList; Loading Loading @@ -432,7 +434,9 @@ public final class AppSearchImpl { try { getResultProto = mIcingSearchEngineLocked.get( createPrefix(packageName, databaseName) + namespace, uri); createPrefix(packageName, databaseName) + namespace, uri, GetResultSpecProto.getDefaultInstance()); } finally { mReadWriteLock.readLock().unlock(); } Loading Loading @@ -691,8 +695,6 @@ public final class AppSearchImpl { * <p>If the app crashes before a call to PersistToDisk(), Icing would trigger a costly recovery * process in next initialization. After that, Icing would still be able to recover all written * data. * * @throws AppSearchException */ public void persistToDisk() throws AppSearchException { PersistToDiskResultProto persistToDiskResultProto = Loading Loading @@ -986,13 +988,12 @@ public final class AppSearchImpl { return false; } List<ResultSpecProto.TypePropertyMask> prefixedTypePropertyMasks = new ArrayList<>(); List<TypePropertyMask> prefixedTypePropertyMasks = new ArrayList<>(); // Rewrite filters to include a database prefix. for (String prefix : existingPrefixes) { Set<String> existingSchemaTypes = mSchemaMapLocked.get(prefix); // Qualify the given schema types for (ResultSpecProto.TypePropertyMask typePropertyMask : resultSpecBuilder.getTypePropertyMasksList()) { for (TypePropertyMask typePropertyMask : resultSpecBuilder.getTypePropertyMasksList()) { String qualifiedType = prefix + typePropertyMask.getSchemaType(); if (existingSchemaTypes.contains(qualifiedType)) { prefixedTypePropertyMasks.add( Loading Loading @@ -1060,12 +1061,36 @@ public final class AppSearchImpl { int delimiterIndex = prefix.indexOf(PACKAGE_DELIMITER); if (delimiterIndex == -1) { // This should never happen if we construct our prefixes properly Log.wtf(TAG, "Malformed prefix doesn't contain package name: " + prefix); Log.wtf(TAG, "Malformed prefix doesn't contain package delimiter: " + prefix); return ""; } return prefix.substring(0, delimiterIndex); } /** * Returns the database name that's contained within the {@code prefix}. * * @param prefix Prefix string that contains the database name inside of it. The database name * must be between the {@link #PACKAGE_DELIMITER} and {@link #DATABASE_DELIMITER} * @return Valid database name. */ @NonNull private static String getDatabaseName(@NonNull String prefix) { int packageDelimiterIndex = prefix.indexOf(PACKAGE_DELIMITER); int databaseDelimiterIndex = prefix.indexOf(DATABASE_DELIMITER); if (packageDelimiterIndex == -1) { // This should never happen if we construct our prefixes properly Log.wtf(TAG, "Malformed prefix doesn't contain package delimiter: " + prefix); return ""; } if (databaseDelimiterIndex == -1) { // This should never happen if we construct our prefixes properly Log.wtf(TAG, "Malformed prefix doesn't contain database delimiter: " + prefix); return ""; } return prefix.substring(packageDelimiterIndex + 1, databaseDelimiterIndex); } @NonNull private static String removePrefix(@NonNull String prefixedString) throws AppSearchException { // The prefix is made up of the package, then the database. So we only need to find the Loading Loading @@ -1178,6 +1203,9 @@ public final class AppSearchImpl { // Parallel array of package names for each document search result. List<String> packageNames = new ArrayList<>(searchResultProto.getResultsCount()); // Parallel array of database names for each document search result. List<String> databaseNames = new ArrayList<>(searchResultProto.getResultsCount()); SearchResultProto.Builder resultsBuilder = searchResultProto.toBuilder(); for (int i = 0; i < searchResultProto.getResultsCount(); i++) { SearchResultProto.ResultProto.Builder resultBuilder = Loading @@ -1185,10 +1213,12 @@ public final class AppSearchImpl { DocumentProto.Builder documentBuilder = resultBuilder.getDocument().toBuilder(); String prefix = removePrefixesFromDocument(documentBuilder); packageNames.add(getPackageName(prefix)); databaseNames.add(getDatabaseName(prefix)); resultBuilder.setDocument(documentBuilder); resultsBuilder.setResults(i, resultBuilder); } return SearchResultToProtoConverter.toSearchResultPage(resultsBuilder, packageNames); return SearchResultToProtoConverter.toSearchResultPage( resultsBuilder, packageNames, databaseNames); } @GuardedBy("mReadWriteLock") Loading
apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchResultToProtoConverter.java +14 −3 Original line number Diff line number Diff line Loading @@ -46,11 +46,16 @@ public class SearchResultToProtoConverter { * @param proto The {@link SearchResultProto} containing results. * @param packageNames A parallel array of package names. The package name at index 'i' of this * list should be the package that indexed the document at index 'i' of proto.getResults(i). * @param databaseNames A parallel array of database names. The database name at index 'i' of * this list shold be the database that indexed the document at index 'i' of * proto.getResults(i). * @return {@link SearchResultPage} of results. */ @NonNull public static SearchResultPage toSearchResultPage( @NonNull SearchResultProtoOrBuilder proto, @NonNull List<String> packageNames) { @NonNull SearchResultProtoOrBuilder proto, @NonNull List<String> packageNames, @NonNull List<String> databaseNames) { Preconditions.checkArgument( proto.getResultsCount() == packageNames.size(), "Size of " + "results does not match the number of package names."); Loading @@ -58,7 +63,9 @@ public class SearchResultToProtoConverter { bundle.putLong(SearchResultPage.NEXT_PAGE_TOKEN_FIELD, proto.getNextPageToken()); ArrayList<Bundle> resultBundles = new ArrayList<>(proto.getResultsCount()); for (int i = 0; i < proto.getResultsCount(); i++) { resultBundles.add(toSearchResultBundle(proto.getResults(i), packageNames.get(i))); resultBundles.add( toSearchResultBundle( proto.getResults(i), packageNames.get(i), databaseNames.get(i))); } bundle.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles); return new SearchResultPage(bundle); Loading @@ -69,16 +76,20 @@ public class SearchResultToProtoConverter { * * @param proto The proto to be converted. * @param packageName The package name associated with the document in {@code proto}. * @param databaseName The database name associated with the document in {@code proto}. * @return A {@link SearchResult} bundle. */ @NonNull private static Bundle toSearchResultBundle( @NonNull SearchResultProto.ResultProtoOrBuilder proto, @NonNull String packageName) { @NonNull SearchResultProto.ResultProtoOrBuilder proto, @NonNull String packageName, @NonNull String databaseName) { Bundle bundle = new Bundle(); GenericDocument document = GenericDocumentToProtoConverter.toGenericDocument(proto.getDocument()); bundle.putBundle(SearchResult.DOCUMENT_FIELD, document.getBundle()); bundle.putString(SearchResult.PACKAGE_NAME_FIELD, packageName); bundle.putString(SearchResult.DATABASE_NAME_FIELD, databaseName); ArrayList<Bundle> matchList = new ArrayList<>(); if (proto.hasSnippet()) { Loading
apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/converter/SearchSpecToProtoConverter.java +3 −3 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import com.google.android.icing.proto.ResultSpecProto; import com.google.android.icing.proto.ScoringSpecProto; import com.google.android.icing.proto.SearchSpecProto; import com.google.android.icing.proto.TermMatchType; import com.google.android.icing.proto.TypePropertyMask; import java.util.List; import java.util.Map; Loading Loading @@ -71,7 +72,7 @@ public final class SearchSpecToProtoConverter { Map<String, List<String>> projectionTypePropertyPaths = spec.getProjections(); for (Map.Entry<String, List<String>> e : projectionTypePropertyPaths.entrySet()) { builder.addTypePropertyMasks( ResultSpecProto.TypePropertyMask.newBuilder() TypePropertyMask.newBuilder() .setSchemaType(e.getKey()) .addAllPaths(e.getValue())); } Loading Loading @@ -107,8 +108,7 @@ public final class SearchSpecToProtoConverter { case SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP: return ScoringSpecProto.RankingStrategy.Code.CREATION_TIMESTAMP; case SearchSpec.RANKING_STRATEGY_RELEVANCE_SCORE: return ScoringSpecProto.RankingStrategy.Code .RELEVANCE_SCORE_NONFUNCTIONAL_PLACEHOLDER; return ScoringSpecProto.RankingStrategy.Code.RELEVANCE_SCORE; default: throw new IllegalArgumentException( "Invalid result ranking strategy: " + rankingStrategyCode); Loading
apex/appsearch/synced_jetpack_changeid.txt +1 −1 Original line number Diff line number Diff line I6745091e5cb97d69ce2e5f85d3d15c073e7e3ef7 Icd58005ad659b6b3d03f683f8954939175324685