Update platform from Jetpack.

Included changes:
* b2c0825: Unhide builders for AppSearch objects to facilitate testing.
* dde789a: Expose Builders for SearchResult and MatchInfo.

Bug: 180143983
Bug: 177954902
Test: Presubmit

Change-Id: I3307cb5fd52b99bcbd72216bb4afbc7b58dd8650
This commit is contained in:
Alexander Dorokhine
2021-03-12 12:12:37 -08:00
parent 096b96158a
commit c02dcf75f4
11 changed files with 310 additions and 125 deletions

View File

@@ -115,7 +115,6 @@ package android.app.appsearch {
public abstract static class AppSearchSchema.PropertyConfig {
method public int getCardinality();
method public int getDataType();
method @NonNull public String getName();
field public static final int CARDINALITY_OPTIONAL = 2; // 0x2
field public static final int CARDINALITY_REPEATED = 1; // 0x1
@@ -265,21 +264,40 @@ package android.app.appsearch {
public final class SearchResult {
method @NonNull public String getDatabaseName();
method @NonNull public android.app.appsearch.GenericDocument getDocument();
method @Deprecated @NonNull public android.app.appsearch.GenericDocument getDocument();
method @NonNull public android.app.appsearch.GenericDocument getGenericDocument();
method @NonNull public java.util.List<android.app.appsearch.SearchResult.MatchInfo> getMatches();
method @NonNull public String getPackageName();
}
public static final class SearchResult.Builder {
ctor public SearchResult.Builder(@NonNull String, @NonNull String);
method @NonNull public android.app.appsearch.SearchResult.Builder addMatch(@NonNull android.app.appsearch.SearchResult.MatchInfo);
method @NonNull public android.app.appsearch.SearchResult build();
method @NonNull public android.app.appsearch.SearchResult.Builder setGenericDocument(@NonNull android.app.appsearch.GenericDocument);
}
public static final class SearchResult.MatchInfo {
method @NonNull public CharSequence getExactMatch();
method @NonNull public android.app.appsearch.SearchResult.MatchRange getExactMatchPosition();
method @Deprecated @NonNull public android.app.appsearch.SearchResult.MatchRange getExactMatchPosition();
method @NonNull public android.app.appsearch.SearchResult.MatchRange getExactMatchRange();
method @NonNull public String getFullText();
method @NonNull public String getPropertyPath();
method @NonNull public CharSequence getSnippet();
method @NonNull public android.app.appsearch.SearchResult.MatchRange getSnippetPosition();
method @Deprecated @NonNull public android.app.appsearch.SearchResult.MatchRange getSnippetPosition();
method @NonNull public android.app.appsearch.SearchResult.MatchRange getSnippetRange();
}
public static final class SearchResult.MatchInfo.Builder {
ctor public SearchResult.MatchInfo.Builder();
method @NonNull public android.app.appsearch.SearchResult.MatchInfo build();
method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setExactMatchRange(@NonNull android.app.appsearch.SearchResult.MatchRange);
method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setPropertyPath(@NonNull String);
method @NonNull public android.app.appsearch.SearchResult.MatchInfo.Builder setSnippetRange(@NonNull android.app.appsearch.SearchResult.MatchRange);
}
public static final class SearchResult.MatchRange {
ctor public SearchResult.MatchRange(int, int);
method public int getEnd();
method public int getStart();
}
@@ -361,6 +379,19 @@ package android.app.appsearch {
method @NonNull public java.util.List<android.app.appsearch.SetSchemaResponse.MigrationFailure> getMigrationFailures();
}
public static final class SetSchemaResponse.Builder {
ctor public SetSchemaResponse.Builder();
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addDeletedType(@NonNull String);
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addDeletedTypes(@NonNull java.util.Collection<java.lang.String>);
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addIncompatibleType(@NonNull String);
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addIncompatibleTypes(@NonNull java.util.Collection<java.lang.String>);
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigratedType(@NonNull String);
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigratedTypes(@NonNull java.util.Collection<java.lang.String>);
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigrationFailure(@NonNull android.app.appsearch.SetSchemaResponse.MigrationFailure);
method @NonNull public android.app.appsearch.SetSchemaResponse.Builder addMigrationFailures(@NonNull java.util.Collection<android.app.appsearch.SetSchemaResponse.MigrationFailure>);
method @NonNull public android.app.appsearch.SetSchemaResponse build();
}
public static class SetSchemaResponse.MigrationFailure {
method @NonNull public android.app.appsearch.AppSearchResult<java.lang.Void> getAppSearchResult();
method @NonNull public String getNamespace();
@@ -368,11 +399,23 @@ package android.app.appsearch {
method @NonNull public String getUri();
}
public static final class SetSchemaResponse.MigrationFailure.Builder {
ctor public SetSchemaResponse.MigrationFailure.Builder();
method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure build();
method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setAppSearchResult(@NonNull android.app.appsearch.AppSearchResult<java.lang.Void>);
method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setNamespace(@NonNull String);
method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setSchemaType(@NonNull String);
method @NonNull public android.app.appsearch.SetSchemaResponse.MigrationFailure.Builder setUri(@NonNull String);
}
}
package android.app.appsearch.exceptions {
public class AppSearchException extends java.lang.Exception {
ctor public AppSearchException(int);
ctor public AppSearchException(int, @Nullable String);
ctor public AppSearchException(int, @Nullable String, @Nullable Throwable);
method public int getResultCode();
method @NonNull public <T> android.app.appsearch.AppSearchResult<T> toAppSearchResult();
}

View File

@@ -309,7 +309,11 @@ public final class AppSearchSchema {
return mBundle.getString(NAME_FIELD, "");
}
/** Returns the type of data the property contains (e.g. string, int, bytes, etc). */
/**
* Returns the type of data the property contains (e.g. string, int, bytes, etc).
*
* @hide
*/
public @DataType int getDataType() {
return mBundle.getInt(DATA_TYPE_FIELD, -1);
}

View File

@@ -32,7 +32,7 @@ import java.util.Objects;
* <p>This allows clients to obtain:
*
* <ul>
* <li>The document which matched, using {@link #getDocument}
* <li>The document which matched, using {@link #getGenericDocument}
* <li>Information about which properties in the document matched, and "snippet" information
* containing textual summaries of the document's matches, using {@link #getMatches}
* </ul>
@@ -43,17 +43,10 @@ import java.util.Objects;
* @see SearchResults
*/
public final class SearchResult {
/** @hide */
public static final String DOCUMENT_FIELD = "document";
/** @hide */
public static final String MATCHES_FIELD = "matches";
/** @hide */
public static final String PACKAGE_NAME_FIELD = "packageName";
/** @hide */
public static final String DATABASE_NAME_FIELD = "databaseName";
static final String DOCUMENT_FIELD = "document";
static final String MATCHES_FIELD = "matches";
static final String PACKAGE_NAME_FIELD = "packageName";
static final String DATABASE_NAME_FIELD = "databaseName";
@NonNull private final Bundle mBundle;
@@ -74,13 +67,20 @@ public final class SearchResult {
return mBundle;
}
/** @deprecated TODO(b/181887768): This method exists only for dogfooder transition. */
@NonNull
@Deprecated
public GenericDocument getDocument() {
return getGenericDocument();
}
/**
* Contains the matching {@link GenericDocument}.
*
* @return Document object which matched the query.
*/
@NonNull
public GenericDocument getDocument() {
public GenericDocument getGenericDocument() {
if (mDocument == null) {
mDocument =
new GenericDocument(
@@ -104,7 +104,7 @@ public final class SearchResult {
Preconditions.checkNotNull(mBundle.getParcelableArrayList(MATCHES_FIELD));
mMatches = new ArrayList<>(matchBundles.size());
for (int i = 0; i < matchBundles.size(); i++) {
MatchInfo matchInfo = new MatchInfo(getDocument(), matchBundles.get(i));
MatchInfo matchInfo = new MatchInfo(matchBundles.get(i), getGenericDocument());
mMatches.add(matchInfo);
}
}
@@ -124,13 +124,69 @@ public final class SearchResult {
/**
* Contains the database name that stored the {@link GenericDocument}.
*
* @return Database name that stored the document
* @return Name of the database within which the document is stored
*/
@NonNull
public String getDatabaseName() {
return Preconditions.checkNotNull(mBundle.getString(DATABASE_NAME_FIELD));
}
/** Builder for {@link SearchResult} objects. */
public static final class Builder {
private final Bundle mBundle = new Bundle();
private final ArrayList<Bundle> mMatchInfos = new ArrayList<>();
private boolean mBuilt;
/**
* Constructs a new builder for {@link SearchResult} objects.
*
* @param packageName the package name the matched document belongs to
* @param databaseName the database name the matched document belongs to.
*/
public Builder(@NonNull String packageName, @NonNull String databaseName) {
mBundle.putString(PACKAGE_NAME_FIELD, Preconditions.checkNotNull(packageName));
mBundle.putString(DATABASE_NAME_FIELD, Preconditions.checkNotNull(databaseName));
}
/**
* Sets the document which matched.
*
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public Builder setGenericDocument(@NonNull GenericDocument document) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBundle.putBundle(DOCUMENT_FIELD, document.getBundle());
return this;
}
/** Adds another match to this SearchResult. */
@NonNull
public Builder addMatch(@NonNull MatchInfo matchInfo) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkState(
matchInfo.mDocument == null,
"This MatchInfo is already associated with a SearchResult and can't be "
+ "reassigned");
mMatchInfos.add(matchInfo.mBundle);
return this;
}
/**
* Constructs a new {@link SearchResult}.
*
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public SearchResult build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBundle.putParcelableArrayList(MATCHES_FIELD, mMatchInfos);
mBuilt = true;
return new SearchResult(mBundle);
}
}
/**
* 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
@@ -147,11 +203,11 @@ public final class SearchResult {
* <p>{@link MatchInfo#getFullText()} returns "A commonly used fake word is foo. Another
* nonsense word thats used a lot is bar."
*
* <p>{@link MatchInfo#getExactMatchPosition()} returns [29, 32]
* <p>{@link MatchInfo#getExactMatchRange()} returns [29, 32]
*
* <p>{@link MatchInfo#getExactMatch()} returns "foo"
*
* <p>{@link MatchInfo#getSnippetPosition()} returns [26, 33]
* <p>{@link MatchInfo#getSnippetRange()} returns [26, 33]
*
* <p>{@link MatchInfo#getSnippet()} returns "is foo."
*
@@ -172,11 +228,11 @@ public final class SearchResult {
*
* <p>{@link MatchInfo#getFullText()} returns "Test Name Jr."
*
* <p>{@link MatchInfo#getExactMatchPosition()} returns [0, 4]
* <p>{@link MatchInfo#getExactMatchRange()} returns [0, 4]
*
* <p>{@link MatchInfo#getExactMatch()} returns "Test"
*
* <p>{@link MatchInfo#getSnippetPosition()} returns [0, 9]
* <p>{@link MatchInfo#getSnippetRange()} returns [0, 9]
*
* <p>{@link MatchInfo#getSnippet()} returns "Test Name"
*
@@ -186,52 +242,54 @@ public final class SearchResult {
*
* <p>{@link MatchInfo#getFullText()} returns "TestNameJr@gmail.com"
*
* <p>{@link MatchInfo#getExactMatchPosition()} returns [0, 20]
* <p>{@link MatchInfo#getExactMatchRange()} returns [0, 20]
*
* <p>{@link MatchInfo#getExactMatch()} returns "TestNameJr@gmail.com"
*
* <p>{@link MatchInfo#getSnippetPosition()} returns [0, 20]
* <p>{@link MatchInfo#getSnippetRange()} returns [0, 20]
*
* <p>{@link MatchInfo#getSnippet()} returns "TestNameJr@gmail.com"
*/
public static final class MatchInfo {
/**
* The path of the matching snippet property.
*
* @hide
*/
public static final String PROPERTY_PATH_FIELD = "propertyPath";
/** The path of the matching snippet property. */
private static final String PROPERTY_PATH_FIELD = "propertyPath";
/** @hide */
public static final String EXACT_MATCH_POSITION_LOWER_FIELD = "exactMatchPositionLower";
private static final String EXACT_MATCH_RANGE_LOWER_FIELD = "exactMatchRangeLower";
private static final String EXACT_MATCH_RANGE_UPPER_FIELD = "exactMatchRangeUpper";
private static final String SNIPPET_RANGE_LOWER_FIELD = "snippetRangeLower";
private static final String SNIPPET_RANGE_UPPER_FIELD = "snippetRangeUpper";
/** @hide */
public static final String EXACT_MATCH_POSITION_UPPER_FIELD = "exactMatchPositionUpper";
/** @hide */
public static final String WINDOW_POSITION_LOWER_FIELD = "windowPositionLower";
/** @hide */
public static final String WINDOW_POSITION_UPPER_FIELD = "windowPositionUpper";
private final String mFullText;
private final String mPropertyPath;
private final Bundle mBundle;
private MatchRange mExactMatchRange;
private MatchRange mWindowRange;
final Bundle mBundle;
MatchInfo(@NonNull GenericDocument document, @NonNull Bundle bundle) {
/**
* Document which the match comes from.
*
* <p>If this is {@code null}, methods which require access to the document, like {@link
* #getExactMatch}, will throw {@link NullPointerException}.
*/
@Nullable final GenericDocument mDocument;
/** Full text of the matched property. Populated on first use. */
@Nullable private String mFullText;
/** Range of property that exactly matched the query. Populated on first use. */
@Nullable private MatchRange mExactMatchRange;
/** Range of some reasonable amount of context around the query. Populated on first use. */
@Nullable private MatchRange mWindowRange;
MatchInfo(@NonNull Bundle bundle, @Nullable GenericDocument document) {
mBundle = Preconditions.checkNotNull(bundle);
Preconditions.checkNotNull(document);
mDocument = document;
mPropertyPath = Preconditions.checkNotNull(bundle.getString(PROPERTY_PATH_FIELD));
mFullText = getPropertyValues(document, mPropertyPath);
}
/**
* Gets the property path corresponding to the given entry.
*
* <p>Property Path: '.' - delimited sequence of property names indicating which property in
* the Document these snippets correspond to.
* <p>A property path is a '.' - delimited sequence of property names indicating which
* property in the document these snippets correspond to.
*
* <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc. For class
* example 1 this returns "subject"
@@ -249,21 +307,34 @@ public final class SearchResult {
*/
@NonNull
public String getFullText() {
if (mFullText == null) {
Preconditions.checkState(
mDocument != null,
"Document has not been populated; this MatchInfo cannot be used yet");
mFullText = getPropertyValues(mDocument, mPropertyPath);
}
return mFullText;
}
/** @deprecated TODO(b/181887768): This method exists only for dogfooder transition. */
@NonNull
@Deprecated
public MatchRange getExactMatchPosition() {
return getExactMatchRange();
}
/**
* Gets the exact {@link MatchRange} corresponding to the given entry.
*
* <p>For class example 1 this returns [29, 32]
*/
@NonNull
public MatchRange getExactMatchPosition() {
public MatchRange getExactMatchRange() {
if (mExactMatchRange == null) {
mExactMatchRange =
new MatchRange(
mBundle.getInt(EXACT_MATCH_POSITION_LOWER_FIELD),
mBundle.getInt(EXACT_MATCH_POSITION_UPPER_FIELD));
mBundle.getInt(EXACT_MATCH_RANGE_LOWER_FIELD),
mBundle.getInt(EXACT_MATCH_RANGE_UPPER_FIELD));
}
return mExactMatchRange;
}
@@ -275,7 +346,14 @@ public final class SearchResult {
*/
@NonNull
public CharSequence getExactMatch() {
return getSubstring(getExactMatchPosition());
return getSubstring(getExactMatchRange());
}
/** @deprecated TODO(b/181887768): This method exists only for dogfooder transition. */
@NonNull
@Deprecated
public MatchRange getSnippetPosition() {
return getSnippetRange();
}
/**
@@ -287,12 +365,12 @@ public final class SearchResult {
* <p>For class example 1 this returns [29, 41].
*/
@NonNull
public MatchRange getSnippetPosition() {
public MatchRange getSnippetRange() {
if (mWindowRange == null) {
mWindowRange =
new MatchRange(
mBundle.getInt(WINDOW_POSITION_LOWER_FIELD),
mBundle.getInt(WINDOW_POSITION_UPPER_FIELD));
mBundle.getInt(SNIPPET_RANGE_LOWER_FIELD),
mBundle.getInt(SNIPPET_RANGE_UPPER_FIELD));
}
return mWindowRange;
}
@@ -309,7 +387,7 @@ public final class SearchResult {
*/
@NonNull
public CharSequence getSnippet() {
return getSubstring(getSnippetPosition());
return getSubstring(getSnippetRange());
}
private CharSequence getSubstring(MatchRange range) {
@@ -331,6 +409,72 @@ public final class SearchResult {
// TODO(b/175146044): Return the proper match based on the index in the propertyName.
return values[0];
}
/** Builder for {@link MatchInfo} objects. */
public static final class Builder {
private final Bundle mBundle = new Bundle();
private boolean mBuilt = false;
/**
* Sets the property path corresponding to the given entry.
*
* <p>A property path is a '.' - delimited sequence of property names indicating which
* property in the document these snippets correspond to.
*
* <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc. For class
* example 1 this returns "subject"
*
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public Builder setPropertyPath(@NonNull String propertyPath) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBundle.putString(
SearchResult.MatchInfo.PROPERTY_PATH_FIELD,
Preconditions.checkNotNull(propertyPath));
return this;
}
/**
* Sets the exact {@link MatchRange} corresponding to the given entry.
*
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public Builder setExactMatchRange(@NonNull MatchRange matchRange) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkNotNull(matchRange);
mBundle.putInt(MatchInfo.EXACT_MATCH_RANGE_LOWER_FIELD, matchRange.getStart());
mBundle.putInt(MatchInfo.EXACT_MATCH_RANGE_UPPER_FIELD, matchRange.getEnd());
return this;
}
/**
* Sets the snippet {@link MatchRange} corresponding to the given entry.
*
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public Builder setSnippetRange(@NonNull MatchRange matchRange) {
Preconditions.checkState(!mBuilt, "Builder has already been used");
Preconditions.checkNotNull(matchRange);
mBundle.putInt(MatchInfo.SNIPPET_RANGE_LOWER_FIELD, matchRange.getStart());
mBundle.putInt(MatchInfo.SNIPPET_RANGE_UPPER_FIELD, matchRange.getEnd());
return this;
}
/**
* Constructs a new {@link MatchInfo}.
*
* @throws IllegalStateException if the builder has already been used
*/
@NonNull
public MatchInfo build() {
Preconditions.checkState(!mBuilt, "Builder has already been used");
mBuilt = true;
return new MatchInfo(mBundle, /*document=*/ null);
}
}
}
/**
@@ -353,7 +497,6 @@ public final class SearchResult {
*
* @param start The start point (inclusive)
* @param end The end point (exclusive)
* @hide
*/
public MatchRange(int start, int end) {
if (start > end) {

View File

@@ -160,12 +160,8 @@ public class SetSchemaResponse {
.addMigrationFailures(mMigrationFailures);
}
/**
* Builder for {@link SetSchemaResponse} objects.
*
* @hide
*/
public static class Builder {
/** Builder for {@link SetSchemaResponse} objects. */
public static final class Builder {
private final ArrayList<MigrationFailure> mMigrationFailures = new ArrayList<>();
private final ArrayList<String> mDeletedTypes = new ArrayList<>();
private final ArrayList<String> mMigratedTypes = new ArrayList<>();
@@ -309,12 +305,8 @@ public class SetSchemaResponse {
mBundle.getString(ERROR_MESSAGE_FIELD, /*defaultValue=*/ ""));
}
/**
* Builder for {@link MigrationFailure} objects.
*
* @hide
*/
public static class Builder {
/** Builder for {@link MigrationFailure} objects. */
public static final class Builder {
private String mSchemaType;
private String mNamespace;
private String mUri;

View File

@@ -32,19 +32,27 @@ public class AppSearchException extends Exception {
/**
* Initializes an {@link AppSearchException} with no message.
*
* @hide
* @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
*/
public AppSearchException(@AppSearchResult.ResultCode int resultCode) {
this(resultCode, /*message=*/ null);
}
/** @hide */
/**
* Initializes an {@link AppSearchException} with a result code and message.
*
* @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
*/
public AppSearchException(
@AppSearchResult.ResultCode int resultCode, @Nullable String message) {
this(resultCode, message, /*cause=*/ null);
}
/** @hide */
/**
* Initializes an {@link AppSearchException} with a result code, message and cause.
*
* @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
*/
public AppSearchException(
@AppSearchResult.ResultCode int resultCode,
@Nullable String message,
@@ -53,12 +61,16 @@ public class AppSearchException extends Exception {
mResultCode = resultCode;
}
/** Returns the result code this exception was constructed with. */
/**
* Returns the result code this exception was constructed with.
*
* @return One of the constants documented in {@link AppSearchResult#getResultCode}.
*/
public @AppSearchResult.ResultCode int getResultCode() {
return mResultCode;
}
/** Converts this {@link java.lang.Exception} into a failed {@link AppSearchResult} */
/** Converts this {@link java.lang.Exception} into a failed {@link AppSearchResult}. */
@NonNull
public <T> AppSearchResult<T> toAppSearchResult() {
return AppSearchResult.newFailedResult(mResultCode, getMessage());

View File

@@ -93,7 +93,7 @@ class AppSearchMigrationHelperImpl implements AppSearchMigrationHelper {
migrator.transform(
currentVersion,
finalVersion,
searchResultPage.getResults().get(i).getDocument());
searchResultPage.getResults().get(i).getGenericDocument());
Bundle bundle = newDocument.getBundle();
Parcel parcel = Parcel.obtain();
parcel.writeBundle(bundle);

View File

@@ -58,14 +58,14 @@ public class SearchResultToProtoConverter {
@NonNull List<String> databaseNames) {
Preconditions.checkArgument(
proto.getResultsCount() == packageNames.size(),
"Size of " + "results does not match the number of package names.");
"Size of results does not match the number of package names.");
Bundle bundle = new Bundle();
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), databaseNames.get(i)));
SearchResult result =
toSearchResult(proto.getResults(i), packageNames.get(i), databaseNames.get(i));
resultBundles.add(result.getBundle());
}
bundle.putParcelableArrayList(SearchResultPage.RESULTS_FIELD, resultBundles);
return new SearchResultPage(bundle);
@@ -80,50 +80,41 @@ public class SearchResultToProtoConverter {
* @return A {@link SearchResult} bundle.
*/
@NonNull
private static Bundle toSearchResultBundle(
private static SearchResult toSearchResult(
@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<>();
SearchResult.Builder builder =
new SearchResult.Builder(packageName, databaseName).setGenericDocument(document);
if (proto.hasSnippet()) {
for (int i = 0; i < proto.getSnippet().getEntriesCount(); i++) {
SnippetProto.EntryProto entry = proto.getSnippet().getEntries(i);
for (int j = 0; j < entry.getSnippetMatchesCount(); j++) {
Bundle matchInfoBundle =
convertToMatchInfoBundle(
entry.getSnippetMatches(j), entry.getPropertyName());
matchList.add(matchInfoBundle);
SearchResult.MatchInfo matchInfo =
toMatchInfo(entry.getSnippetMatches(j), entry.getPropertyName());
builder.addMatch(matchInfo);
}
}
}
bundle.putParcelableArrayList(SearchResult.MATCHES_FIELD, matchList);
return bundle;
return builder.build();
}
private static Bundle convertToMatchInfoBundle(
SnippetMatchProto snippetMatchProto, String propertyPath) {
Bundle bundle = new Bundle();
bundle.putString(SearchResult.MatchInfo.PROPERTY_PATH_FIELD, propertyPath);
bundle.putInt(
SearchResult.MatchInfo.EXACT_MATCH_POSITION_LOWER_FIELD,
snippetMatchProto.getExactMatchPosition());
bundle.putInt(
SearchResult.MatchInfo.EXACT_MATCH_POSITION_UPPER_FIELD,
snippetMatchProto.getExactMatchPosition() + snippetMatchProto.getExactMatchBytes());
bundle.putInt(
SearchResult.MatchInfo.WINDOW_POSITION_LOWER_FIELD,
snippetMatchProto.getWindowPosition());
bundle.putInt(
SearchResult.MatchInfo.WINDOW_POSITION_UPPER_FIELD,
snippetMatchProto.getWindowPosition() + snippetMatchProto.getWindowBytes());
return bundle;
private static SearchResult.MatchInfo toMatchInfo(
@NonNull SnippetMatchProto snippetMatchProto, @NonNull String propertyPath) {
return new SearchResult.MatchInfo.Builder()
.setPropertyPath(propertyPath)
.setExactMatchRange(
new SearchResult.MatchRange(
snippetMatchProto.getExactMatchPosition(),
snippetMatchProto.getExactMatchPosition()
+ snippetMatchProto.getExactMatchBytes()))
.setSnippetRange(
new SearchResult.MatchRange(
snippetMatchProto.getWindowPosition(),
snippetMatchProto.getWindowPosition()
+ snippetMatchProto.getWindowBytes()))
.build();
}
}

View File

@@ -1 +1 @@
I42b89416968565ceb6483b400894f5b49524208c
I1926fb1d13628607f7a513c8149b65dd86c98dd6

View File

@@ -80,7 +80,7 @@ public class AppSearchTestUtils {
List<GenericDocument> documents = new ArrayList<>();
while (results.size() > 0) {
for (SearchResult result : results) {
documents.add(result.getDocument());
documents.add(result.getGenericDocument());
}
results = searchResults.getNextPage().get();
}

View File

@@ -632,7 +632,7 @@ public class AppSearchImplTest {
// No query filters specified. package2 should only get its own documents back.
searchResultPage = mAppSearchImpl.query("package2", "database2", "", searchSpec);
assertThat(searchResultPage.getResults()).hasSize(1);
assertThat(searchResultPage.getResults().get(0).getDocument()).isEqualTo(document);
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
}
/**
@@ -692,7 +692,7 @@ public class AppSearchImplTest {
.build();
searchResultPage = mAppSearchImpl.query("package2", "database2", "", searchSpec);
assertThat(searchResultPage.getResults()).hasSize(1);
assertThat(searchResultPage.getResults().get(0).getDocument()).isEqualTo(document);
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
}
@Test
@@ -1073,7 +1073,7 @@ public class AppSearchImplTest {
for (SearchResult result : searchResultPage.getResults()) {
assertThat(result.getPackageName()).isEqualTo("com.package.foo");
assertThat(result.getDatabaseName()).isEqualTo("databaseName");
assertThat(result.getDocument())
assertThat(result.getGenericDocument())
.isEqualTo(
GenericDocumentToProtoConverter.toGenericDocument(
strippedDocumentProto.build()));

View File

@@ -93,10 +93,10 @@ public class SnippetTest {
assertThat(match.getPropertyPath()).isEqualTo(propertyKeyString);
assertThat(match.getFullText()).isEqualTo(propertyValueString);
assertThat(match.getExactMatch()).isEqualTo(exactMatch);
assertThat(match.getExactMatchPosition())
assertThat(match.getExactMatchRange())
.isEqualTo(new SearchResult.MatchRange(/*lower=*/ 29, /*upper=*/ 32));
assertThat(match.getFullText()).isEqualTo(propertyValueString);
assertThat(match.getSnippetPosition())
assertThat(match.getSnippetRange())
.isEqualTo(new SearchResult.MatchRange(/*lower=*/ 26, /*upper=*/ 32));
assertThat(match.getSnippet()).isEqualTo(window);
}
@@ -210,20 +210,20 @@ public class SnippetTest {
SearchResult.MatchInfo match1 = result.getMatches().get(0);
assertThat(match1.getPropertyPath()).isEqualTo("sender.name");
assertThat(match1.getFullText()).isEqualTo("Test Name Jr.");
assertThat(match1.getExactMatchPosition())
assertThat(match1.getExactMatchRange())
.isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 4));
assertThat(match1.getExactMatch()).isEqualTo("Test");
assertThat(match1.getSnippetPosition())
assertThat(match1.getSnippetRange())
.isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 9));
assertThat(match1.getSnippet()).isEqualTo("Test Name");
SearchResult.MatchInfo match2 = result.getMatches().get(1);
assertThat(match2.getPropertyPath()).isEqualTo("sender.email");
assertThat(match2.getFullText()).isEqualTo("TestNameJr@gmail.com");
assertThat(match2.getExactMatchPosition())
assertThat(match2.getExactMatchRange())
.isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
assertThat(match2.getExactMatch()).isEqualTo("TestNameJr@gmail.com");
assertThat(match2.getSnippetPosition())
assertThat(match2.getSnippetRange())
.isEqualTo(new SearchResult.MatchRange(/*lower=*/ 0, /*upper=*/ 20));
assertThat(match2.getSnippet()).isEqualTo("TestNameJr@gmail.com");
}