Merge "Update framework from jetpack." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5d3d644cbc
@@ -96,8 +96,13 @@ public class SetSchemaResponse {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Set} of schema type that were deleted by the {@link
|
||||
* AppSearchSession#setSchema} call.
|
||||
* Returns a {@link Set} of deleted schema types.
|
||||
*
|
||||
* <p>A "deleted" type is a schema type that was previously a part of the database schema but
|
||||
* was not present in the {@link SetSchemaRequest} object provided in the
|
||||
* {@link AppSearchSession#setSchema) call.
|
||||
*
|
||||
* <p>Documents for a deleted type are removed from the database.
|
||||
*/
|
||||
@NonNull
|
||||
public Set<String> getDeletedTypes() {
|
||||
@@ -113,6 +118,15 @@ public class SetSchemaResponse {
|
||||
/**
|
||||
* Returns a {@link Set} of schema type that were migrated by the {@link
|
||||
* AppSearchSession#setSchema} call.
|
||||
*
|
||||
* <p>A "migrated" type is a schema type that has triggered a {@link Migrator} instance to
|
||||
* migrate documents of the schema type to another schema type, or to another version of the
|
||||
* schema type.
|
||||
*
|
||||
* <p>If a document fails to be migrated, a {@link MigrationFailure} will be generated for that
|
||||
* document.
|
||||
*
|
||||
* @see Migrator
|
||||
*/
|
||||
@NonNull
|
||||
public Set<String> getMigratedTypes() {
|
||||
@@ -132,6 +146,7 @@ public class SetSchemaResponse {
|
||||
* <p>If a {@link Migrator} is provided for this type and the migration is success triggered.
|
||||
* The type will also appear in {@link #getMigratedTypes()}.
|
||||
*
|
||||
* @see SetSchemaRequest
|
||||
* @see AppSearchSession#setSchema
|
||||
* @see SetSchemaRequest.Builder#setForceOverride
|
||||
*/
|
||||
|
||||
@@ -42,6 +42,8 @@ public class AppSearchException extends Exception {
|
||||
* Initializes an {@link AppSearchException} with a result code and message.
|
||||
*
|
||||
* @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
|
||||
* @param message The detail message (which is saved for later retrieval by the {@link
|
||||
* #getMessage()} method).
|
||||
*/
|
||||
public AppSearchException(
|
||||
@AppSearchResult.ResultCode int resultCode, @Nullable String message) {
|
||||
@@ -52,6 +54,11 @@ public class AppSearchException extends Exception {
|
||||
* Initializes an {@link AppSearchException} with a result code, message and cause.
|
||||
*
|
||||
* @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
|
||||
* @param message The detail message (which is saved for later retrieval by the {@link
|
||||
* #getMessage()} method).
|
||||
* @param cause The cause (which is saved for later retrieval by the {@link #getCause()}
|
||||
* method). (A null value is permitted, and indicates that the cause is nonexistent or
|
||||
* unknown.)
|
||||
*/
|
||||
public AppSearchException(
|
||||
@AppSearchResult.ResultCode int resultCode,
|
||||
|
||||
@@ -501,7 +501,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
packageName,
|
||||
databaseName,
|
||||
queryExpression,
|
||||
new SearchSpec(searchSpecBundle));
|
||||
new SearchSpec(searchSpecBundle),
|
||||
/*logger=*/ null);
|
||||
invokeCallbackOnResult(
|
||||
callback,
|
||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||
@@ -535,7 +536,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
queryExpression,
|
||||
new SearchSpec(searchSpecBundle),
|
||||
packageName,
|
||||
callingUid);
|
||||
callingUid,
|
||||
/*logger=*/ null);
|
||||
invokeCallbackOnResult(
|
||||
callback,
|
||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||
@@ -609,7 +611,8 @@ public class AppSearchManagerService extends SystemService {
|
||||
packageName,
|
||||
databaseName,
|
||||
queryExpression,
|
||||
new SearchSpec(searchSpecBundle));
|
||||
new SearchSpec(searchSpecBundle),
|
||||
/*logger=*/ null);
|
||||
while (!searchResultPage.getResults().isEmpty()) {
|
||||
for (int i = 0; i < searchResultPage.getResults().size(); i++) {
|
||||
AppSearchMigrationHelper.writeBundleToOutputStream(
|
||||
|
||||
@@ -149,7 +149,8 @@ public final class ImplInstanceManager {
|
||||
private AppSearchImpl createImpl(@NonNull Context context, @UserIdInt int userId)
|
||||
throws AppSearchException {
|
||||
File appSearchDir = getAppSearchDir(userId);
|
||||
return AppSearchImpl.create(appSearchDir, context, userId, mGlobalQuerierPackage);
|
||||
return AppSearchImpl.create(
|
||||
appSearchDir, context, userId, mGlobalQuerierPackage, /*logger=*/ null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,9 @@ import com.android.server.appsearch.external.localstorage.converter.SearchResult
|
||||
import com.android.server.appsearch.external.localstorage.converter.SearchSpecToProtoConverter;
|
||||
import com.android.server.appsearch.external.localstorage.converter.SetSchemaResponseToProtoConverter;
|
||||
import com.android.server.appsearch.external.localstorage.converter.TypePropertyPathToProtoConverter;
|
||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||
|
||||
import com.google.android.icing.IcingSearchEngine;
|
||||
import com.google.android.icing.proto.DeleteByQueryResultProto;
|
||||
@@ -178,28 +180,63 @@ public final class AppSearchImpl implements Closeable {
|
||||
/**
|
||||
* Creates and initializes an instance of {@link AppSearchImpl} which writes data to the given
|
||||
* folder.
|
||||
*
|
||||
* <p>Clients can pass a {@link AppSearchLogger} here through their AppSearchSession, but it
|
||||
* can't be saved inside {@link AppSearchImpl}, because the impl will be shared by all the
|
||||
* sessions for the same package in JetPack.
|
||||
*
|
||||
* <p>Instead, logger instance needs to be passed to each individual method, like create, query
|
||||
* and putDocument.
|
||||
*
|
||||
* @param logger collects stats for initialization if provided.
|
||||
*/
|
||||
@NonNull
|
||||
public static AppSearchImpl create(
|
||||
@NonNull File icingDir,
|
||||
@NonNull Context context,
|
||||
int userId,
|
||||
@NonNull String globalQuerierPackage)
|
||||
@NonNull String globalQuerierPackage,
|
||||
@Nullable AppSearchLogger logger)
|
||||
throws AppSearchException {
|
||||
Objects.requireNonNull(icingDir);
|
||||
Objects.requireNonNull(context);
|
||||
Objects.requireNonNull(globalQuerierPackage);
|
||||
|
||||
long totalLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||
InitializeStats.Builder initStatsBuilder = null;
|
||||
if (logger != null) {
|
||||
initStatsBuilder = new InitializeStats.Builder();
|
||||
}
|
||||
|
||||
AppSearchImpl appSearchImpl =
|
||||
new AppSearchImpl(icingDir, context, userId, globalQuerierPackage);
|
||||
new AppSearchImpl(
|
||||
icingDir, context, userId, globalQuerierPackage, initStatsBuilder);
|
||||
|
||||
long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||
appSearchImpl.initializeVisibilityStore();
|
||||
long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
|
||||
|
||||
if (logger != null && initStatsBuilder != null) {
|
||||
initStatsBuilder
|
||||
.setTotalLatencyMillis(
|
||||
(int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis))
|
||||
.setPrepareVisibilityStoreLatencyMillis(
|
||||
(int)
|
||||
(prepareVisibilityStoreLatencyEndMillis
|
||||
- prepareVisibilityStoreLatencyStartMillis));
|
||||
logger.logStats(initStatsBuilder.build());
|
||||
}
|
||||
|
||||
return appSearchImpl;
|
||||
}
|
||||
|
||||
/** @param initStatsBuilder collects stats for initialization if provided. */
|
||||
private AppSearchImpl(
|
||||
@NonNull File icingDir,
|
||||
@NonNull Context context,
|
||||
int userId,
|
||||
@NonNull String globalQuerierPackage)
|
||||
@NonNull String globalQuerierPackage,
|
||||
@Nullable InitializeStats.Builder initStatsBuilder)
|
||||
throws AppSearchException {
|
||||
mReadWriteLock.writeLock().lock();
|
||||
|
||||
@@ -211,13 +248,24 @@ public final class AppSearchImpl implements Closeable {
|
||||
.setBaseDir(icingDir.getAbsolutePath())
|
||||
.build();
|
||||
mIcingSearchEngineLocked = new IcingSearchEngine(options);
|
||||
|
||||
mVisibilityStoreLocked =
|
||||
new VisibilityStore(this, context, userId, globalQuerierPackage);
|
||||
|
||||
InitializeResultProto initializeResultProto = mIcingSearchEngineLocked.initialize();
|
||||
|
||||
if (initStatsBuilder != null) {
|
||||
initStatsBuilder
|
||||
.setStatusCode(
|
||||
statusProtoToAppSearchException(initializeResultProto.getStatus())
|
||||
.getResultCode())
|
||||
// TODO(b/173532925) how to get DeSyncs value
|
||||
.setHasDeSync(false);
|
||||
AppSearchLoggerHelper.copyNativeStats(
|
||||
initializeResultProto.getInitializeStats(), initStatsBuilder);
|
||||
}
|
||||
|
||||
long prepareSchemaAndNamespacesLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||
SchemaProto schemaProto;
|
||||
GetAllNamespacesResultProto getAllNamespacesResultProto;
|
||||
GetAllNamespacesResultProto getAllNamespacesResultProto = null;
|
||||
try {
|
||||
checkSuccess(initializeResultProto.getStatus());
|
||||
schemaProto = getSchemaProtoLocked();
|
||||
@@ -225,6 +273,17 @@ public final class AppSearchImpl implements Closeable {
|
||||
checkSuccess(getAllNamespacesResultProto.getStatus());
|
||||
} catch (AppSearchException e) {
|
||||
Log.w(TAG, "Error initializing, resetting IcingSearchEngine.", e);
|
||||
if (initStatsBuilder != null && getAllNamespacesResultProto != null) {
|
||||
initStatsBuilder
|
||||
.setStatusCode(
|
||||
statusProtoToAppSearchException(
|
||||
getAllNamespacesResultProto.getStatus())
|
||||
.getResultCode())
|
||||
.setPrepareSchemaAndNamespacesLatencyMillis(
|
||||
(int)
|
||||
(SystemClock.elapsedRealtime()
|
||||
- prepareSchemaAndNamespacesLatencyStartMillis));
|
||||
}
|
||||
// Some error. Reset and see if it fixes it.
|
||||
resetLocked();
|
||||
return;
|
||||
@@ -240,6 +299,14 @@ public final class AppSearchImpl implements Closeable {
|
||||
for (String prefixedNamespace : getAllNamespacesResultProto.getNamespacesList()) {
|
||||
addToMap(mNamespaceMapLocked, getPrefix(prefixedNamespace), prefixedNamespace);
|
||||
}
|
||||
|
||||
// logging prepare_schema_and_namespaces latency
|
||||
if (initStatsBuilder != null) {
|
||||
initStatsBuilder.setPrepareSchemaAndNamespacesLatencyMillis(
|
||||
(int)
|
||||
(SystemClock.elapsedRealtime()
|
||||
- prepareSchemaAndNamespacesLatencyStartMillis));
|
||||
}
|
||||
} finally {
|
||||
mReadWriteLock.writeLock().unlock();
|
||||
}
|
||||
@@ -539,7 +606,7 @@ public final class AppSearchImpl implements Closeable {
|
||||
addToMap(mNamespaceMapLocked, prefix, documentBuilder.getNamespace());
|
||||
|
||||
// Logging stats
|
||||
if (logger != null) {
|
||||
if (logger != null && pStatsBuilder != null) {
|
||||
pStatsBuilder
|
||||
.getGeneralStatsBuilder()
|
||||
.setStatusCode(
|
||||
@@ -562,7 +629,7 @@ public final class AppSearchImpl implements Closeable {
|
||||
} finally {
|
||||
mReadWriteLock.writeLock().unlock();
|
||||
|
||||
if (logger != null) {
|
||||
if (logger != null && pStatsBuilder != null) {
|
||||
long totalEndTimeMillis = SystemClock.elapsedRealtime();
|
||||
pStatsBuilder
|
||||
.getGeneralStatsBuilder()
|
||||
@@ -644,6 +711,7 @@ public final class AppSearchImpl implements Closeable {
|
||||
* @param databaseName The databaseName this query for.
|
||||
* @param queryExpression Query String to search.
|
||||
* @param searchSpec Spec for setting filters, raw query etc.
|
||||
* @param logger logger to collect query stats
|
||||
* @return The results of performing this search. It may contain an empty list of results if no
|
||||
* documents matched the query.
|
||||
* @throws AppSearchException on IcingSearchEngine error.
|
||||
@@ -653,8 +721,17 @@ public final class AppSearchImpl implements Closeable {
|
||||
@NonNull String packageName,
|
||||
@NonNull String databaseName,
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec)
|
||||
@NonNull SearchSpec searchSpec,
|
||||
@Nullable AppSearchLogger logger)
|
||||
throws AppSearchException {
|
||||
long totalLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||
SearchStats.Builder sStatsBuilder = null;
|
||||
if (logger != null) {
|
||||
sStatsBuilder =
|
||||
new SearchStats.Builder(SearchStats.VISIBILITY_SCOPE_LOCAL, packageName)
|
||||
.setDatabase(databaseName);
|
||||
}
|
||||
|
||||
mReadWriteLock.readLock().lock();
|
||||
try {
|
||||
throwIfClosedLocked();
|
||||
@@ -673,9 +750,15 @@ public final class AppSearchImpl implements Closeable {
|
||||
Collections.singleton(createPrefix(packageName, databaseName)),
|
||||
allowedPrefixedSchemas,
|
||||
queryExpression,
|
||||
searchSpec);
|
||||
searchSpec,
|
||||
sStatsBuilder);
|
||||
} finally {
|
||||
mReadWriteLock.readLock().unlock();
|
||||
if (logger != null && sStatsBuilder != null) {
|
||||
sStatsBuilder.setTotalLatencyMillis(
|
||||
(int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis));
|
||||
logger.logStats(sStatsBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,6 +772,7 @@ public final class AppSearchImpl implements Closeable {
|
||||
* @param searchSpec Spec for setting filters, raw query etc.
|
||||
* @param callerPackageName Package name of the caller, should belong to the {@code callerUid}.
|
||||
* @param callerUid UID of the client making the globalQuery call.
|
||||
* @param logger logger to collect globalQuery stats
|
||||
* @return The results of performing this search. It may contain an empty list of results if no
|
||||
* documents matched the query.
|
||||
* @throws AppSearchException on IcingSearchEngine error.
|
||||
@@ -698,8 +782,16 @@ public final class AppSearchImpl implements Closeable {
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec,
|
||||
@NonNull String callerPackageName,
|
||||
int callerUid)
|
||||
int callerUid,
|
||||
@Nullable AppSearchLogger logger)
|
||||
throws AppSearchException {
|
||||
long totalLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||
SearchStats.Builder sStatsBuilder = null;
|
||||
if (logger != null) {
|
||||
sStatsBuilder =
|
||||
new SearchStats.Builder(SearchStats.VISIBILITY_SCOPE_GLOBAL, callerPackageName);
|
||||
}
|
||||
|
||||
mReadWriteLock.readLock().lock();
|
||||
try {
|
||||
throwIfClosedLocked();
|
||||
@@ -754,9 +846,19 @@ public final class AppSearchImpl implements Closeable {
|
||||
}
|
||||
|
||||
return doQueryLocked(
|
||||
prefixFilters, allowedPrefixedSchemas, queryExpression, searchSpec);
|
||||
prefixFilters,
|
||||
allowedPrefixedSchemas,
|
||||
queryExpression,
|
||||
searchSpec,
|
||||
sStatsBuilder);
|
||||
} finally {
|
||||
mReadWriteLock.readLock().unlock();
|
||||
|
||||
if (logger != null && sStatsBuilder != null) {
|
||||
sStatsBuilder.setTotalLatencyMillis(
|
||||
(int) (SystemClock.elapsedRealtime() - totalLatencyStartMillis));
|
||||
logger.logStats(sStatsBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,8 +896,11 @@ public final class AppSearchImpl implements Closeable {
|
||||
@NonNull Set<String> prefixes,
|
||||
@NonNull Set<String> allowedPrefixedSchemas,
|
||||
@NonNull String queryExpression,
|
||||
@NonNull SearchSpec searchSpec)
|
||||
@NonNull SearchSpec searchSpec,
|
||||
@Nullable SearchStats.Builder sStatsBuilder)
|
||||
throws AppSearchException {
|
||||
long rewriteSearchSpecLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||
|
||||
SearchSpecProto.Builder searchSpecBuilder =
|
||||
SearchSpecToProtoConverter.toSearchSpecProto(searchSpec).toBuilder()
|
||||
.setQuery(queryExpression);
|
||||
@@ -804,9 +909,17 @@ public final class AppSearchImpl implements Closeable {
|
||||
// sending request to Icing.
|
||||
if (!rewriteSearchSpecForPrefixesLocked(
|
||||
searchSpecBuilder, prefixes, allowedPrefixedSchemas)) {
|
||||
if (sStatsBuilder != null) {
|
||||
sStatsBuilder.setRewriteSearchSpecLatencyMillis(
|
||||
(int)
|
||||
(SystemClock.elapsedRealtime()
|
||||
- rewriteSearchSpecLatencyStartMillis));
|
||||
}
|
||||
return new SearchResultPage(Bundle.EMPTY);
|
||||
}
|
||||
|
||||
// rewriteSearchSpec, rewriteResultSpec and convertScoringSpec are all counted in
|
||||
// rewriteSearchSpecLatencyMillis
|
||||
ResultSpecProto.Builder resultSpecBuilder =
|
||||
SearchSpecToProtoConverter.toResultSpecProto(searchSpec).toBuilder();
|
||||
|
||||
@@ -822,15 +935,38 @@ public final class AppSearchImpl implements Closeable {
|
||||
addPerNamespaceResultGroupingsLocked(
|
||||
resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
|
||||
}
|
||||
rewriteResultSpecForPrefixesLocked(resultSpecBuilder, prefixes, allowedPrefixedSchemas);
|
||||
|
||||
rewriteResultSpecForPrefixesLocked(resultSpecBuilder, prefixes, allowedPrefixedSchemas);
|
||||
ScoringSpecProto scoringSpec = SearchSpecToProtoConverter.toScoringSpecProto(searchSpec);
|
||||
|
||||
long rewriteSearchSpecLatencyEndMillis = SystemClock.elapsedRealtime();
|
||||
|
||||
SearchResultProto searchResultProto =
|
||||
mIcingSearchEngineLocked.search(
|
||||
searchSpecBuilder.build(), scoringSpec, resultSpecBuilder.build());
|
||||
|
||||
if (sStatsBuilder != null) {
|
||||
sStatsBuilder
|
||||
.setStatusCode(
|
||||
statusProtoToAppSearchException(searchResultProto.getStatus())
|
||||
.getResultCode())
|
||||
.setRewriteSearchSpecLatencyMillis(
|
||||
(int)
|
||||
(rewriteSearchSpecLatencyEndMillis
|
||||
- rewriteSearchSpecLatencyStartMillis));
|
||||
AppSearchLoggerHelper.copyNativeStats(searchResultProto.getQueryStats(), sStatsBuilder);
|
||||
}
|
||||
|
||||
checkSuccess(searchResultProto.getStatus());
|
||||
|
||||
return rewriteSearchResultProto(searchResultProto, mSchemaMapLocked);
|
||||
long rewriteSearchResultLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||
SearchResultPage resultPage = rewriteSearchResultProto(searchResultProto, mSchemaMapLocked);
|
||||
if (sStatsBuilder != null) {
|
||||
sStatsBuilder.setRewriteSearchResultLatencyMillis(
|
||||
(int) (SystemClock.elapsedRealtime() - rewriteSearchResultLatencyStartMillis));
|
||||
}
|
||||
|
||||
return resultPage;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,9 @@ import android.annotation.NonNull;
|
||||
import android.app.appsearch.exceptions.AppSearchException;
|
||||
|
||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||
|
||||
/**
|
||||
* An interface for implementing client-defined logging AppSearch operations stats.
|
||||
@@ -39,5 +41,11 @@ public interface AppSearchLogger {
|
||||
/** Logs {@link PutDocumentStats} */
|
||||
void logStats(@NonNull PutDocumentStats stats) throws AppSearchException;
|
||||
|
||||
/** Logs {@link InitializeStats} */
|
||||
void logStats(@NonNull InitializeStats stats) throws AppSearchException;
|
||||
|
||||
/** Logs {@link SearchStats} */
|
||||
void logStats(@NonNull SearchStats stats) throws AppSearchException;
|
||||
|
||||
// TODO(b/173532925) Add remaining logStats once we add all the stats.
|
||||
}
|
||||
|
||||
@@ -18,9 +18,13 @@ package com.android.server.appsearch.external.localstorage;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||
|
||||
import com.google.android.icing.proto.InitializeStatsProto;
|
||||
import com.google.android.icing.proto.PutDocumentStatsProto;
|
||||
import com.google.android.icing.proto.QueryStatsProto;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -35,7 +39,7 @@ public final class AppSearchLoggerHelper {
|
||||
private AppSearchLoggerHelper() {}
|
||||
|
||||
/**
|
||||
* Copies native stats to builder.
|
||||
* Copies native PutDocument stats to builder.
|
||||
*
|
||||
* @param fromNativeStats stats copied from
|
||||
* @param toStatsBuilder stats copied to
|
||||
@@ -56,4 +60,64 @@ public final class AppSearchLoggerHelper {
|
||||
.setNativeExceededMaxNumTokens(
|
||||
fromNativeStats.getTokenizationStats().getExceededMaxTokenNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies native Initialize stats to builder.
|
||||
*
|
||||
* @param fromNativeStats stats copied from
|
||||
* @param toStatsBuilder stats copied to
|
||||
*/
|
||||
static void copyNativeStats(
|
||||
@NonNull InitializeStatsProto fromNativeStats,
|
||||
@NonNull InitializeStats.Builder toStatsBuilder) {
|
||||
Objects.requireNonNull(fromNativeStats);
|
||||
Objects.requireNonNull(toStatsBuilder);
|
||||
toStatsBuilder
|
||||
.setNativeLatencyMillis(fromNativeStats.getLatencyMs())
|
||||
.setDocumentStoreRecoveryCause(
|
||||
fromNativeStats.getDocumentStoreRecoveryCause().getNumber())
|
||||
.setIndexRestorationCause(fromNativeStats.getIndexRestorationCause().getNumber())
|
||||
.setSchemaStoreRecoveryCause(
|
||||
fromNativeStats.getSchemaStoreRecoveryCause().getNumber())
|
||||
.setDocumentStoreRecoveryLatencyMillis(
|
||||
fromNativeStats.getDocumentStoreRecoveryLatencyMs())
|
||||
.setIndexRestorationLatencyMillis(fromNativeStats.getIndexRestorationLatencyMs())
|
||||
.setSchemaStoreRecoveryLatencyMillis(
|
||||
fromNativeStats.getSchemaStoreRecoveryLatencyMs())
|
||||
.setDocumentStoreDataStatus(
|
||||
fromNativeStats.getDocumentStoreDataStatus().getNumber())
|
||||
.setDocumentCount(fromNativeStats.getNumDocuments())
|
||||
.setSchemaTypeCount(fromNativeStats.getNumSchemaTypes());
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy native Query stats to buiilder.
|
||||
*
|
||||
* @param fromNativeStats Stats copied from.
|
||||
* @param toStatsBuilder Stats copied to.
|
||||
*/
|
||||
static void copyNativeStats(
|
||||
@NonNull QueryStatsProto fromNativeStats, @NonNull SearchStats.Builder toStatsBuilder) {
|
||||
Objects.requireNonNull(fromNativeStats);
|
||||
Objects.requireNonNull(toStatsBuilder);
|
||||
toStatsBuilder
|
||||
.setNativeLatencyMillis(fromNativeStats.getLatencyMs())
|
||||
.setTermCount(fromNativeStats.getNumTerms())
|
||||
// TODO(b/173532925) query length missing in native
|
||||
// .setNativeQueryLength(0)
|
||||
.setFilteredNamespaceCount(fromNativeStats.getNumNamespacesFiltered())
|
||||
.setFilteredSchemaTypeCount(fromNativeStats.getNumSchemaTypesFiltered())
|
||||
.setRequestedPageSize(fromNativeStats.getRequestedPageSize())
|
||||
.setCurrentPageReturnedResultCount(
|
||||
fromNativeStats.getNumResultsReturnedCurrentPage())
|
||||
.setIsFirstPage(fromNativeStats.getIsFirstPage())
|
||||
.setParseQueryLatencyMillis(fromNativeStats.getParseQueryLatencyMs())
|
||||
.setRankingStrategy(fromNativeStats.getRankingStrategy().getNumber())
|
||||
.setScoredDocumentCount(fromNativeStats.getNumDocumentsScored())
|
||||
.setScoringLatencyMillis(fromNativeStats.getScoringLatencyMs())
|
||||
.setRankingLatencyMillis(fromNativeStats.getRankingLatencyMs())
|
||||
.setResultWithSnippetsCount(fromNativeStats.getNumResultsWithSnippets())
|
||||
.setDocumentRetrievingLatencyMillis(
|
||||
fromNativeStats.getDocumentRetrievalLatencyMs());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright 2021 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.server.appsearch.external.localstorage.stats;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.appsearch.AppSearchResult;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class holds detailed stats for initialization
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class InitializeStats {
|
||||
/**
|
||||
* The cause of IcingSearchEngine recovering from a previous bad state during initialization.
|
||||
*/
|
||||
@IntDef(
|
||||
value = {
|
||||
// It needs to be sync with RecoveryCause in
|
||||
// external/icing/proto/icing/proto/logging.proto#InitializeStatsProto
|
||||
RECOVERY_CAUSE_NONE,
|
||||
RECOVERY_CAUSE_DATA_LOSS,
|
||||
RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH,
|
||||
RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH,
|
||||
RECOVERY_CAUSE_IO_ERROR,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface RecoveryCause {}
|
||||
|
||||
// No recovery happened.
|
||||
public static final int RECOVERY_CAUSE_NONE = 0;
|
||||
// Data loss in ground truth.
|
||||
public static final int RECOVERY_CAUSE_DATA_LOSS = 1;
|
||||
// Data in index is inconsistent with ground truth.
|
||||
public static final int RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH = 2;
|
||||
// Total checksum of all the components does not match.
|
||||
public static final int RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH = 3;
|
||||
// Random I/O errors.
|
||||
public static final int RECOVERY_CAUSE_IO_ERROR = 4;
|
||||
|
||||
/** Status regarding how much data is lost during the initialization. */
|
||||
@IntDef(
|
||||
value = {
|
||||
// It needs to be sync with DocumentStoreDataStatus in
|
||||
// external/icing/proto/icing/proto/logging.proto#InitializeStatsProto
|
||||
|
||||
DOCUMENT_STORE_DATA_STATUS_NO_DATA_LOSS,
|
||||
DOCUMENT_STORE_DATA_STATUS_PARTIAL_LOSS,
|
||||
DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface DocumentStoreDataStatus {}
|
||||
|
||||
// Document store is successfully initialized or fully recovered.
|
||||
public static final int DOCUMENT_STORE_DATA_STATUS_NO_DATA_LOSS = 0;
|
||||
// Ground truth data is partially lost.
|
||||
public static final int DOCUMENT_STORE_DATA_STATUS_PARTIAL_LOSS = 1;
|
||||
// Ground truth data is completely lost.
|
||||
public static final int DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS = 2;
|
||||
|
||||
@AppSearchResult.ResultCode private final int mStatusCode;
|
||||
private final int mTotalLatencyMillis;
|
||||
/** Whether the initialize() detects deSync. */
|
||||
private final boolean mHasDeSync;
|
||||
/** Time used to read and process the schema and namespaces. */
|
||||
private final int mPrepareSchemaAndNamespacesLatencyMillis;
|
||||
/** Time used to read and process the visibility store. */
|
||||
private final int mPrepareVisibilityStoreLatencyMillis;
|
||||
/** Overall time used for the native function call. */
|
||||
private final int mNativeLatencyMillis;
|
||||
|
||||
@RecoveryCause private final int mNativeDocumentStoreRecoveryCause;
|
||||
@RecoveryCause private final int mNativeIndexRestorationCause;
|
||||
@RecoveryCause private final int mNativeSchemaStoreRecoveryCause;
|
||||
/** Time used to recover the document store. */
|
||||
private final int mNativeDocumentStoreRecoveryLatencyMillis;
|
||||
/** Time used to restore the index. */
|
||||
private final int mNativeIndexRestorationLatencyMillis;
|
||||
/** Time used to recover the schema store. */
|
||||
private final int mNativeSchemaStoreRecoveryLatencyMillis;
|
||||
/** Status regarding how much data is lost during the initialization. */
|
||||
private final int mNativeDocumentStoreDataStatus;
|
||||
/**
|
||||
* Returns number of documents currently in document store. Those may include alive, deleted,
|
||||
* and expired documents.
|
||||
*/
|
||||
private final int mNativeNumDocuments;
|
||||
/** Returns number of schema types currently in the schema store. */
|
||||
private final int mNativeNumSchemaTypes;
|
||||
|
||||
/** Returns the status of the initialization. */
|
||||
@AppSearchResult.ResultCode
|
||||
public int getStatusCode() {
|
||||
return mStatusCode;
|
||||
}
|
||||
|
||||
/** Returns the total latency in milliseconds for the initialization. */
|
||||
public int getTotalLatencyMillis() {
|
||||
return mTotalLatencyMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the initialize() detects deSync.
|
||||
*
|
||||
* <p>If there is a deSync, it means AppSearch and IcingSearchEngine have an inconsistent view
|
||||
* of what data should exist.
|
||||
*/
|
||||
public boolean hasDeSync() {
|
||||
return mHasDeSync;
|
||||
}
|
||||
|
||||
/** Returns time used to read and process the schema and namespaces. */
|
||||
public int getPrepareSchemaAndNamespacesLatencyMillis() {
|
||||
return mPrepareSchemaAndNamespacesLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns time used to read and process the visibility file. */
|
||||
public int getPrepareVisibilityStoreLatencyMillis() {
|
||||
return mPrepareVisibilityStoreLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns overall time used for the native function call. */
|
||||
public int getNativeLatencyMillis() {
|
||||
return mNativeLatencyMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns recovery cause for document store.
|
||||
*
|
||||
* <p>Possible recovery causes for document store:
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_DATA_LOSS}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
|
||||
*/
|
||||
@RecoveryCause
|
||||
public int getDocumentStoreRecoveryCause() {
|
||||
return mNativeDocumentStoreRecoveryCause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns restoration cause for index store.
|
||||
*
|
||||
* <p>Possible causes:
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_INCONSISTENT_WITH_GROUND_TRUTH}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
|
||||
*/
|
||||
@RecoveryCause
|
||||
public int getIndexRestorationCause() {
|
||||
return mNativeIndexRestorationCause;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns recovery cause for schema store.
|
||||
*
|
||||
* <p>Possible causes:
|
||||
* <li>IO_ERROR
|
||||
*/
|
||||
@RecoveryCause
|
||||
public int getSchemaStoreRecoveryCause() {
|
||||
return mNativeSchemaStoreRecoveryCause;
|
||||
}
|
||||
|
||||
/** Returns time used to recover the document store. */
|
||||
public int getDocumentStoreRecoveryLatencyMillis() {
|
||||
return mNativeDocumentStoreRecoveryLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns time used to restore the index. */
|
||||
public int getIndexRestorationLatencyMillis() {
|
||||
return mNativeIndexRestorationLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns time used to recover the schema store. */
|
||||
public int getSchemaStoreRecoveryLatencyMillis() {
|
||||
return mNativeSchemaStoreRecoveryLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns status about how much data is lost during the initialization. */
|
||||
@DocumentStoreDataStatus
|
||||
public int getDocumentStoreDataStatus() {
|
||||
return mNativeDocumentStoreDataStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of documents currently in document store. Those may include alive, deleted,
|
||||
* and expired documents.
|
||||
*/
|
||||
public int getDocumentCount() {
|
||||
return mNativeNumDocuments;
|
||||
}
|
||||
|
||||
/** Returns number of schema types currently in the schema store. */
|
||||
public int getSchemaTypeCount() {
|
||||
return mNativeNumSchemaTypes;
|
||||
}
|
||||
|
||||
InitializeStats(@NonNull Builder builder) {
|
||||
Objects.requireNonNull(builder);
|
||||
mStatusCode = builder.mStatusCode;
|
||||
mTotalLatencyMillis = builder.mTotalLatencyMillis;
|
||||
mHasDeSync = builder.mHasDeSync;
|
||||
mPrepareSchemaAndNamespacesLatencyMillis = builder.mPrepareSchemaAndNamespacesLatencyMillis;
|
||||
mPrepareVisibilityStoreLatencyMillis = builder.mPrepareVisibilityStoreLatencyMillis;
|
||||
mNativeLatencyMillis = builder.mNativeLatencyMillis;
|
||||
mNativeDocumentStoreRecoveryCause = builder.mNativeDocumentStoreRecoveryCause;
|
||||
mNativeIndexRestorationCause = builder.mNativeIndexRestorationCause;
|
||||
mNativeSchemaStoreRecoveryCause = builder.mNativeSchemaStoreRecoveryCause;
|
||||
mNativeDocumentStoreRecoveryLatencyMillis =
|
||||
builder.mNativeDocumentStoreRecoveryLatencyMillis;
|
||||
mNativeIndexRestorationLatencyMillis = builder.mNativeIndexRestorationLatencyMillis;
|
||||
mNativeSchemaStoreRecoveryLatencyMillis = builder.mNativeSchemaStoreRecoveryLatencyMillis;
|
||||
mNativeDocumentStoreDataStatus = builder.mNativeDocumentStoreDataStatus;
|
||||
mNativeNumDocuments = builder.mNativeNumDocuments;
|
||||
mNativeNumSchemaTypes = builder.mNativeNumSchemaTypes;
|
||||
}
|
||||
|
||||
/** Builder for {@link InitializeStats}. */
|
||||
public static class Builder {
|
||||
@AppSearchResult.ResultCode int mStatusCode;
|
||||
int mTotalLatencyMillis;
|
||||
boolean mHasDeSync;
|
||||
int mPrepareSchemaAndNamespacesLatencyMillis;
|
||||
int mPrepareVisibilityStoreLatencyMillis;
|
||||
int mNativeLatencyMillis;
|
||||
@RecoveryCause int mNativeDocumentStoreRecoveryCause;
|
||||
@RecoveryCause int mNativeIndexRestorationCause;
|
||||
@RecoveryCause int mNativeSchemaStoreRecoveryCause;
|
||||
int mNativeDocumentStoreRecoveryLatencyMillis;
|
||||
int mNativeIndexRestorationLatencyMillis;
|
||||
int mNativeSchemaStoreRecoveryLatencyMillis;
|
||||
@DocumentStoreDataStatus int mNativeDocumentStoreDataStatus;
|
||||
int mNativeNumDocuments;
|
||||
int mNativeNumSchemaTypes;
|
||||
|
||||
/** Sets the status of the initialization. */
|
||||
@NonNull
|
||||
public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
|
||||
mStatusCode = statusCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the total latency of the initialization in milliseconds. */
|
||||
@NonNull
|
||||
public Builder setTotalLatencyMillis(int totalLatencyMillis) {
|
||||
mTotalLatencyMillis = totalLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the initialize() detects deSync.
|
||||
*
|
||||
* <p>If there is a deSync, it means AppSearch and IcingSearchEngine have an inconsistent
|
||||
* view of what data should exist.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setHasDeSync(boolean hasDeSync) {
|
||||
mHasDeSync = hasDeSync;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to read and process the schema and namespaces. */
|
||||
@NonNull
|
||||
public Builder setPrepareSchemaAndNamespacesLatencyMillis(
|
||||
int prepareSchemaAndNamespacesLatencyMillis) {
|
||||
mPrepareSchemaAndNamespacesLatencyMillis = prepareSchemaAndNamespacesLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to read and process the visibility file. */
|
||||
@NonNull
|
||||
public Builder setPrepareVisibilityStoreLatencyMillis(
|
||||
int prepareVisibilityStoreLatencyMillis) {
|
||||
mPrepareVisibilityStoreLatencyMillis = prepareVisibilityStoreLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets overall time used for the native function call. */
|
||||
@NonNull
|
||||
public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
|
||||
mNativeLatencyMillis = nativeLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets recovery cause for document store.
|
||||
*
|
||||
* <p>Possible recovery causes for document store:
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_DATA_LOSS}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDocumentStoreRecoveryCause(
|
||||
@RecoveryCause int documentStoreRecoveryCause) {
|
||||
mNativeDocumentStoreRecoveryCause = documentStoreRecoveryCause;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets restoration cause for index store.
|
||||
*
|
||||
* <p>Possible causes:
|
||||
* <li>{@link InitializeStats#DOCUMENT_STORE_DATA_STATUS_COMPLETE_LOSS}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_TOTAL_CHECKSUM_MISMATCH}
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setIndexRestorationCause(@RecoveryCause int indexRestorationCause) {
|
||||
mNativeIndexRestorationCause = indexRestorationCause;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns recovery cause for schema store.
|
||||
*
|
||||
* <p>Possible causes:
|
||||
* <li>{@link InitializeStats#RECOVERY_CAUSE_IO_ERROR}
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setSchemaStoreRecoveryCause(@RecoveryCause int schemaStoreRecoveryCause) {
|
||||
mNativeSchemaStoreRecoveryCause = schemaStoreRecoveryCause;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to recover the document store. */
|
||||
@NonNull
|
||||
public Builder setDocumentStoreRecoveryLatencyMillis(
|
||||
int documentStoreRecoveryLatencyMillis) {
|
||||
mNativeDocumentStoreRecoveryLatencyMillis = documentStoreRecoveryLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to restore the index. */
|
||||
@NonNull
|
||||
public Builder setIndexRestorationLatencyMillis(int indexRestorationLatencyMillis) {
|
||||
mNativeIndexRestorationLatencyMillis = indexRestorationLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to recover the schema store. */
|
||||
@NonNull
|
||||
public Builder setSchemaStoreRecoveryLatencyMillis(int schemaStoreRecoveryLatencyMillis) {
|
||||
mNativeSchemaStoreRecoveryLatencyMillis = schemaStoreRecoveryLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Native Document Store Data status. status is defined in
|
||||
* external/icing/proto/icing/proto/logging.proto
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDocumentStoreDataStatus(
|
||||
@DocumentStoreDataStatus int documentStoreDataStatus) {
|
||||
mNativeDocumentStoreDataStatus = documentStoreDataStatus;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets number of documents currently in document store. Those may include alive, deleted,
|
||||
* and expired documents.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setDocumentCount(int numDocuments) {
|
||||
mNativeNumDocuments = numDocuments;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets number of schema types currently in the schema store. */
|
||||
@NonNull
|
||||
public Builder setSchemaTypeCount(int numSchemaTypes) {
|
||||
mNativeNumSchemaTypes = numSchemaTypes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link InitializeStats} from the contents of this {@link
|
||||
* InitializeStats.Builder}
|
||||
*/
|
||||
@NonNull
|
||||
public InitializeStats build() {
|
||||
return new InitializeStats(/* builder= */ this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
/*
|
||||
* Copyright 2021 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.server.appsearch.external.localstorage.stats;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.appsearch.AppSearchResult;
|
||||
import android.app.appsearch.SearchSpec;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class holds detailed stats for {@link android.app.appsearch.AppSearchSession#search(String,
|
||||
* SearchSpec)}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class SearchStats {
|
||||
@IntDef(
|
||||
value = {
|
||||
// Searches apps' own documents.
|
||||
VISIBILITY_SCOPE_LOCAL,
|
||||
// Searches the global documents. Including platform surfaceable and 3p-access.
|
||||
VISIBILITY_SCOPE_GLOBAL,
|
||||
// TODO(b/173532925) Add THIRD_PARTY_ACCESS once we can distinguish platform
|
||||
// surfaceable from 3p access(right both of them are categorized as
|
||||
// VISIBILITY_SCOPE_GLOBAL)
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface VisibilityScope {}
|
||||
|
||||
// Searches apps' own documents.
|
||||
public static final int VISIBILITY_SCOPE_LOCAL = 1;
|
||||
// Searches the global documents. Including platform surfaceable and 3p-access.
|
||||
public static final int VISIBILITY_SCOPE_GLOBAL = 2;
|
||||
|
||||
@NonNull private final String mPackageName;
|
||||
@Nullable private final String mDatabase;
|
||||
/**
|
||||
* The status code returned by {@link AppSearchResult#getResultCode()} for the call or internal
|
||||
* state.
|
||||
*/
|
||||
@AppSearchResult.ResultCode private final int mStatusCode;
|
||||
|
||||
private final int mTotalLatencyMillis;
|
||||
/** Time used to rewrite the search spec. */
|
||||
private final int mRewriteSearchSpecLatencyMillis;
|
||||
/** Time used to rewrite the search results. */
|
||||
private final int mRewriteSearchResultLatencyMillis;
|
||||
/** Defines the scope the query is searching over */
|
||||
@VisibilityScope private final int mVisibilityScope;
|
||||
/** Overall time used for the native function call. */
|
||||
private final int mNativeLatencyMillis;
|
||||
/** Number of terms in the query string. */
|
||||
private final int mNativeNumTerms;
|
||||
/** Length of the query string. */
|
||||
private final int mNativeQueryLength;
|
||||
/** Number of namespaces filtered. */
|
||||
private final int mNativeNumNamespacesFiltered;
|
||||
/** Number of schema types filtered. */
|
||||
private final int mNativeNumSchemaTypesFiltered;
|
||||
/** The requested number of results in one page. */
|
||||
private final int mNativeRequestedPageSize;
|
||||
/** The actual number of results returned in the current page. */
|
||||
private final int mNativeNumResultsReturnedCurrentPage;
|
||||
/**
|
||||
* Whether the function call is querying the first page. If it's not, Icing will fetch the
|
||||
* results from cache so that some steps may be skipped.
|
||||
*/
|
||||
private final boolean mNativeIsFirstPage;
|
||||
/**
|
||||
* Time used to parse the query, including 2 parts: tokenizing and transforming tokens into an
|
||||
* iterator tree.
|
||||
*/
|
||||
private final int mNativeParseQueryLatencyMillis;
|
||||
/** Strategy of scoring and ranking. */
|
||||
@SearchSpec.RankingStrategy private final int mNativeRankingStrategy;
|
||||
/** Number of documents scored. */
|
||||
private final int mNativeNumDocumentsScored;
|
||||
/** Time used to score the raw results. */
|
||||
private final int mNativeScoringLatencyMillis;
|
||||
/** Time used to rank the scored results. */
|
||||
private final int mNativeRankingLatencyMillis;
|
||||
/**
|
||||
* Time used to fetch the document protos. Note that it includes the time to snippet if {@link
|
||||
* SearchStats#mNativeNumResultsWithSnippets} is greater than 0.
|
||||
*/
|
||||
private final int mNativeDocumentRetrievingLatencyMillis;
|
||||
/** How many snippets are calculated. */
|
||||
private final int mNativeNumResultsWithSnippets;
|
||||
|
||||
SearchStats(@NonNull Builder builder) {
|
||||
Objects.requireNonNull(builder);
|
||||
mPackageName = builder.mPackageName;
|
||||
mDatabase = builder.mDatabase;
|
||||
mStatusCode = builder.mStatusCode;
|
||||
mTotalLatencyMillis = builder.mTotalLatencyMillis;
|
||||
mRewriteSearchSpecLatencyMillis = builder.mRewriteSearchSpecLatencyMillis;
|
||||
mRewriteSearchResultLatencyMillis = builder.mRewriteSearchResultLatencyMillis;
|
||||
mVisibilityScope = builder.mVisibilityScope;
|
||||
mNativeLatencyMillis = builder.mNativeLatencyMillis;
|
||||
mNativeNumTerms = builder.mNativeNumTerms;
|
||||
mNativeQueryLength = builder.mNativeQueryLength;
|
||||
mNativeNumNamespacesFiltered = builder.mNativeNumNamespacesFiltered;
|
||||
mNativeNumSchemaTypesFiltered = builder.mNativeNumSchemaTypesFiltered;
|
||||
mNativeRequestedPageSize = builder.mNativeRequestedPageSize;
|
||||
mNativeNumResultsReturnedCurrentPage = builder.mNativeNumResultsReturnedCurrentPage;
|
||||
mNativeIsFirstPage = builder.mNativeIsFirstPage;
|
||||
mNativeParseQueryLatencyMillis = builder.mNativeParseQueryLatencyMillis;
|
||||
mNativeRankingStrategy = builder.mNativeRankingStrategy;
|
||||
mNativeNumDocumentsScored = builder.mNativeNumDocumentsScored;
|
||||
mNativeScoringLatencyMillis = builder.mNativeScoringLatencyMillis;
|
||||
mNativeRankingLatencyMillis = builder.mNativeRankingLatencyMillis;
|
||||
mNativeNumResultsWithSnippets = builder.mNativeNumResultsWithSnippets;
|
||||
mNativeDocumentRetrievingLatencyMillis = builder.mNativeDocumentRetrievingLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns the package name of the session. */
|
||||
@NonNull
|
||||
public String getPackageName() {
|
||||
return mPackageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database name of the session.
|
||||
*
|
||||
* @return database name used by the session. {@code null} if and only if it is a global
|
||||
* search(visibilityScope is {@link SearchStats#VISIBILITY_SCOPE_GLOBAL}).
|
||||
*/
|
||||
@Nullable
|
||||
public String getDatabase() {
|
||||
return mDatabase;
|
||||
}
|
||||
|
||||
/** Returns status of the search. */
|
||||
@AppSearchResult.ResultCode
|
||||
public int getStatusCode() {
|
||||
return mStatusCode;
|
||||
}
|
||||
|
||||
/** Returns the total latency of the search. */
|
||||
public int getTotalLatencyMillis() {
|
||||
return mTotalLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns how much time spent on rewriting the {@link SearchSpec}. */
|
||||
public int getRewriteSearchSpecLatencyMillis() {
|
||||
return mRewriteSearchSpecLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns how much time spent on rewriting the {@link android.app.appsearch.SearchResult}. */
|
||||
public int getRewriteSearchResultLatencyMillis() {
|
||||
return mRewriteSearchResultLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns the visibility scope of the search. */
|
||||
@VisibilityScope
|
||||
public int getVisibilityScope() {
|
||||
return mVisibilityScope;
|
||||
}
|
||||
|
||||
/** Returns how much time spent on the native calls. */
|
||||
public int getNativeLatencyMillis() {
|
||||
return mNativeLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns number of terms in the search string. */
|
||||
public int getTermCount() {
|
||||
return mNativeNumTerms;
|
||||
}
|
||||
|
||||
/** Returns the length of the search string. */
|
||||
public int getQueryLength() {
|
||||
return mNativeQueryLength;
|
||||
}
|
||||
|
||||
/** Returns number of namespaces filtered. */
|
||||
public int getFilteredNamespaceCount() {
|
||||
return mNativeNumNamespacesFiltered;
|
||||
}
|
||||
|
||||
/** Returns number of schema types filtered. */
|
||||
public int getFilteredSchemaTypeCount() {
|
||||
return mNativeNumSchemaTypesFiltered;
|
||||
}
|
||||
|
||||
/** Returns the requested number of results in one page. */
|
||||
public int getRequestedPageSize() {
|
||||
return mNativeRequestedPageSize;
|
||||
}
|
||||
|
||||
/** Returns the actual number of results returned in the current page. */
|
||||
public int getCurrentPageReturnedResultCount() {
|
||||
return mNativeNumResultsReturnedCurrentPage;
|
||||
}
|
||||
|
||||
// TODO(b/185184738) Make it an integer to show how many pages having been returned.
|
||||
/** Returns whether the function call is querying the first page. */
|
||||
public boolean isFirstPage() {
|
||||
return mNativeIsFirstPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time used to parse the query, including 2 parts: tokenizing and transforming tokens
|
||||
* into an iterator tree.
|
||||
*/
|
||||
public int getParseQueryLatencyMillis() {
|
||||
return mNativeParseQueryLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns strategy of scoring and ranking. */
|
||||
@SearchSpec.RankingStrategy
|
||||
public int getRankingStrategy() {
|
||||
return mNativeRankingStrategy;
|
||||
}
|
||||
|
||||
/** Returns number of documents scored. */
|
||||
public int getScoredDocumentCount() {
|
||||
return mNativeNumDocumentsScored;
|
||||
}
|
||||
|
||||
/** Returns time used to score the raw results. */
|
||||
public int getScoringLatencyMillis() {
|
||||
return mNativeScoringLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns time used to rank the scored results. */
|
||||
public int getRankingLatencyMillis() {
|
||||
return mNativeRankingLatencyMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time used to fetch the document protos. Note that it includes the time to snippet if
|
||||
* {@link SearchStats#mNativeNumResultsWithSnippets} is not zero.
|
||||
*/
|
||||
public int getDocumentRetrievingLatencyMillis() {
|
||||
return mNativeDocumentRetrievingLatencyMillis;
|
||||
}
|
||||
|
||||
/** Returns the number of the results in the page returned were snippeted. */
|
||||
public int getResultWithSnippetsCount() {
|
||||
return mNativeNumResultsWithSnippets;
|
||||
}
|
||||
|
||||
/** Builder for {@link SearchStats} */
|
||||
public static class Builder {
|
||||
@NonNull final String mPackageName;
|
||||
@Nullable String mDatabase;
|
||||
@AppSearchResult.ResultCode int mStatusCode;
|
||||
int mTotalLatencyMillis;
|
||||
int mRewriteSearchSpecLatencyMillis;
|
||||
int mRewriteSearchResultLatencyMillis;
|
||||
int mVisibilityScope;
|
||||
int mNativeLatencyMillis;
|
||||
int mNativeNumTerms;
|
||||
int mNativeQueryLength;
|
||||
int mNativeNumNamespacesFiltered;
|
||||
int mNativeNumSchemaTypesFiltered;
|
||||
int mNativeRequestedPageSize;
|
||||
int mNativeNumResultsReturnedCurrentPage;
|
||||
boolean mNativeIsFirstPage;
|
||||
int mNativeParseQueryLatencyMillis;
|
||||
int mNativeRankingStrategy;
|
||||
int mNativeNumDocumentsScored;
|
||||
int mNativeScoringLatencyMillis;
|
||||
int mNativeRankingLatencyMillis;
|
||||
int mNativeNumResultsWithSnippets;
|
||||
int mNativeDocumentRetrievingLatencyMillis;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param visibilityScope scope for the corresponding search.
|
||||
* @param packageName name of the calling package.
|
||||
*/
|
||||
public Builder(@VisibilityScope int visibilityScope, @NonNull String packageName) {
|
||||
mVisibilityScope = visibilityScope;
|
||||
mPackageName = Objects.requireNonNull(packageName);
|
||||
}
|
||||
|
||||
/** Sets the database used by the session. */
|
||||
@NonNull
|
||||
public Builder setDatabase(@NonNull String database) {
|
||||
mDatabase = Objects.requireNonNull(database);
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the status of the search. */
|
||||
@NonNull
|
||||
public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
|
||||
mStatusCode = statusCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets total latency for the search. */
|
||||
@NonNull
|
||||
public Builder setTotalLatencyMillis(int totalLatencyMillis) {
|
||||
mTotalLatencyMillis = totalLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to rewrite the search spec. */
|
||||
@NonNull
|
||||
public Builder setRewriteSearchSpecLatencyMillis(int rewriteSearchSpecLatencyMillis) {
|
||||
mRewriteSearchSpecLatencyMillis = rewriteSearchSpecLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to rewrite the search results. */
|
||||
@NonNull
|
||||
public Builder setRewriteSearchResultLatencyMillis(int rewriteSearchResultLatencyMillis) {
|
||||
mRewriteSearchResultLatencyMillis = rewriteSearchResultLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets overall time used for the native function calls. */
|
||||
@NonNull
|
||||
public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
|
||||
mNativeLatencyMillis = nativeLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets number of terms in the search string. */
|
||||
@NonNull
|
||||
public Builder setTermCount(int termCount) {
|
||||
mNativeNumTerms = termCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets length of the search string. */
|
||||
@NonNull
|
||||
public Builder setQueryLength(int queryLength) {
|
||||
mNativeQueryLength = queryLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets number of namespaces filtered. */
|
||||
@NonNull
|
||||
public Builder setFilteredNamespaceCount(int filteredNamespaceCount) {
|
||||
mNativeNumNamespacesFiltered = filteredNamespaceCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets number of schema types filtered. */
|
||||
@NonNull
|
||||
public Builder setFilteredSchemaTypeCount(int filteredSchemaTypeCount) {
|
||||
mNativeNumSchemaTypesFiltered = filteredSchemaTypeCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the requested number of results in one page. */
|
||||
@NonNull
|
||||
public Builder setRequestedPageSize(int requestedPageSize) {
|
||||
mNativeRequestedPageSize = requestedPageSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the actual number of results returned in the current page. */
|
||||
@NonNull
|
||||
public Builder setCurrentPageReturnedResultCount(int currentPageReturnedResultCount) {
|
||||
mNativeNumResultsReturnedCurrentPage = currentPageReturnedResultCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the function call is querying the first page. If it's not, Icing will fetch
|
||||
* the results from cache so that some steps may be skipped.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setIsFirstPage(boolean nativeIsFirstPage) {
|
||||
mNativeIsFirstPage = nativeIsFirstPage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets time used to parse the query, including 2 parts: tokenizing and transforming tokens
|
||||
* into an iterator tree.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setParseQueryLatencyMillis(int parseQueryLatencyMillis) {
|
||||
mNativeParseQueryLatencyMillis = parseQueryLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets strategy of scoring and ranking. */
|
||||
@NonNull
|
||||
public Builder setRankingStrategy(@SearchSpec.RankingStrategy int rankingStrategy) {
|
||||
mNativeRankingStrategy = rankingStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets number of documents scored. */
|
||||
@NonNull
|
||||
public Builder setScoredDocumentCount(int scoredDocumentCount) {
|
||||
mNativeNumDocumentsScored = scoredDocumentCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to score the raw results. */
|
||||
@NonNull
|
||||
public Builder setScoringLatencyMillis(int scoringLatencyMillis) {
|
||||
mNativeScoringLatencyMillis = scoringLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to rank the scored results. */
|
||||
@NonNull
|
||||
public Builder setRankingLatencyMillis(int rankingLatencyMillis) {
|
||||
mNativeRankingLatencyMillis = rankingLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets time used to fetch the document protos. */
|
||||
@NonNull
|
||||
public Builder setDocumentRetrievingLatencyMillis(int documentRetrievingLatencyMillis) {
|
||||
mNativeDocumentRetrievingLatencyMillis = documentRetrievingLatencyMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets how many snippets are calculated. */
|
||||
@NonNull
|
||||
public Builder setResultWithSnippetsCount(int resultWithSnippetsCount) {
|
||||
mNativeNumResultsWithSnippets = resultWithSnippetsCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link SearchStats} from the contents of this {@link
|
||||
* SearchStats.Builder}.
|
||||
*/
|
||||
@NonNull
|
||||
public SearchStats build() {
|
||||
if (mDatabase == null) {
|
||||
Preconditions.checkState(
|
||||
mVisibilityScope != SearchStats.VISIBILITY_SCOPE_LOCAL,
|
||||
"database can not be null if visibilityScope is local.");
|
||||
}
|
||||
|
||||
return new SearchStats(/* builder= */ this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,9 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.server.appsearch.external.localstorage.AppSearchLogger;
|
||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
@@ -189,6 +191,16 @@ public final class PlatformLogger implements AppSearchLogger {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logStats(@NonNull InitializeStats stats) throws AppSearchException {
|
||||
// TODO(b/173532925): Implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logStats(@NonNull SearchStats stats) throws AppSearchException {
|
||||
// TODO(b/173532925): Implement
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes cached UID for package.
|
||||
*
|
||||
|
||||
@@ -1 +1 @@
|
||||
I06df2c636d26419e653c5d8c9e7d15449da6816e
|
||||
I19dac52031c47099f621eced9f148931f1021f25
|
||||
|
||||
@@ -70,7 +70,8 @@ public class AppSearchImplPlatformTest {
|
||||
mTemporaryFolder.newFolder(),
|
||||
mContext,
|
||||
mContext.getUserId(),
|
||||
mContext.getPackageName());
|
||||
mContext.getPackageName(),
|
||||
/*logger=*/ null);
|
||||
mGlobalQuerierUid =
|
||||
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
||||
}
|
||||
@@ -117,9 +118,8 @@ public class AppSearchImplPlatformTest {
|
||||
// No query filters specified, global query can retrieve all documents.
|
||||
SearchSpec searchSpec =
|
||||
new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY).build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.globalQuery(
|
||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
|
||||
SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
|
||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).hasSize(2);
|
||||
|
||||
// Document2 will be first since it got indexed later and has a "better", aka more recent
|
||||
@@ -174,9 +174,8 @@ public class AppSearchImplPlatformTest {
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||
.addFilterPackageNames("package1")
|
||||
.build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.globalQuery(
|
||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
|
||||
SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
|
||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
|
||||
|
||||
@@ -186,9 +185,8 @@ public class AppSearchImplPlatformTest {
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||
.addFilterPackageNames("package2")
|
||||
.build();
|
||||
searchResultPage =
|
||||
mAppSearchImpl.globalQuery(
|
||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
|
||||
searchResultPage = mAppSearchImpl.globalQuery(
|
||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,8 @@ public class VisibilityStoreTest {
|
||||
mTemporaryFolder.newFolder(),
|
||||
mContext,
|
||||
mContext.getUserId(),
|
||||
/*globalQuerierPackage=*/ mContext.getPackageName());
|
||||
/*globalQuerierPackage=*/ mContext.getPackageName(),
|
||||
/*logger=*/ null);
|
||||
mGlobalQuerierUid =
|
||||
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
||||
|
||||
@@ -163,7 +164,8 @@ public class VisibilityStoreTest {
|
||||
mTemporaryFolder.newFolder(),
|
||||
mContext,
|
||||
mContext.getUserId(),
|
||||
/*globalQuerierPackage=*/ mContext.getPackageName());
|
||||
/*globalQuerierPackage=*/ mContext.getPackageName(),
|
||||
/*logger=*/ null);
|
||||
VisibilityStore visibilityStore = appSearchImpl.getVisibilityStoreLocked();
|
||||
|
||||
// Use some arbitrary callerUid. If we can't find the global querier's uid though,
|
||||
|
||||
@@ -82,7 +82,8 @@ public class AppSearchImplTest {
|
||||
mTemporaryFolder.newFolder(),
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ context.getPackageName());
|
||||
/*globalQuerierPackage=*/ context.getPackageName(),
|
||||
/*logger=*/ null);
|
||||
}
|
||||
|
||||
// TODO(b/175430168) add test to verify reset is working properly.
|
||||
@@ -604,7 +605,7 @@ public class AppSearchImplTest {
|
||||
SearchSpec searchSpec =
|
||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.query("package", "EmptyDatabase", "", searchSpec);
|
||||
mAppSearchImpl.query("package", "EmptyDatabase", "", searchSpec, /*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).isEmpty();
|
||||
}
|
||||
|
||||
@@ -647,7 +648,7 @@ public class AppSearchImplTest {
|
||||
SearchSpec searchSpec =
|
||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.query("package2", "database2", "", searchSpec);
|
||||
mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).isEmpty();
|
||||
|
||||
// Insert package2 document
|
||||
@@ -655,7 +656,9 @@ public class AppSearchImplTest {
|
||||
mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
|
||||
|
||||
// No query filters specified. package2 should only get its own documents back.
|
||||
searchResultPage = mAppSearchImpl.query("package2", "database2", "", searchSpec);
|
||||
searchResultPage =
|
||||
mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=
|
||||
*/ null);
|
||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
||||
}
|
||||
@@ -703,7 +706,7 @@ public class AppSearchImplTest {
|
||||
.addFilterPackageNames("package1")
|
||||
.build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.query("package2", "database2", "", searchSpec);
|
||||
mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).isEmpty();
|
||||
|
||||
// Insert package2 document
|
||||
@@ -716,7 +719,9 @@ public class AppSearchImplTest {
|
||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||
.addFilterPackageNames("package2")
|
||||
.build();
|
||||
searchResultPage = mAppSearchImpl.query("package2", "database2", "", searchSpec);
|
||||
searchResultPage =
|
||||
mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=
|
||||
*/ null);
|
||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
||||
}
|
||||
@@ -727,7 +732,11 @@ public class AppSearchImplTest {
|
||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.globalQuery(
|
||||
"", searchSpec, /*callerPackageName=*/ "", /*callerUid=*/ 0);
|
||||
"",
|
||||
searchSpec,
|
||||
/*callerPackageName=*/ "",
|
||||
/*callerUid=*/ 0,
|
||||
/*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).isEmpty();
|
||||
}
|
||||
|
||||
@@ -1033,7 +1042,12 @@ public class AppSearchImplTest {
|
||||
SearchSpec searchSpec =
|
||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.query("package", "database", /*queryExpression=*/ "", searchSpec);
|
||||
mAppSearchImpl.query(
|
||||
"package",
|
||||
"database",
|
||||
/*queryExpression=*/ "",
|
||||
searchSpec,
|
||||
/*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
||||
|
||||
@@ -1042,7 +1056,12 @@ public class AppSearchImplTest {
|
||||
|
||||
// Verify the document is cleared.
|
||||
searchResultPage =
|
||||
mAppSearchImpl.query("package2", "database2", /*queryExpression=*/ "", searchSpec);
|
||||
mAppSearchImpl.query(
|
||||
"package2",
|
||||
"database2",
|
||||
/*queryExpression=*/ "",
|
||||
searchSpec,
|
||||
/*logger=*/ null);
|
||||
assertThat(searchResultPage.getResults()).isEmpty();
|
||||
|
||||
// Verify the schema is cleared.
|
||||
@@ -1244,7 +1263,8 @@ public class AppSearchImplTest {
|
||||
new SearchSpec.Builder()
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
||||
.setRankingStrategy(SearchSpec.RANKING_STRATEGY_USAGE_COUNT)
|
||||
.build())
|
||||
.build(),
|
||||
/*logger=*/ null)
|
||||
.getResults();
|
||||
assertThat(page).hasSize(2);
|
||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
|
||||
@@ -1262,7 +1282,8 @@ public class AppSearchImplTest {
|
||||
.setRankingStrategy(
|
||||
SearchSpec
|
||||
.RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP)
|
||||
.build())
|
||||
.build(),
|
||||
/*logger=*/ null)
|
||||
.getResults();
|
||||
assertThat(page).hasSize(2);
|
||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
|
||||
@@ -1279,7 +1300,8 @@ public class AppSearchImplTest {
|
||||
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
||||
.setRankingStrategy(
|
||||
SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT)
|
||||
.build())
|
||||
.build(),
|
||||
/*logger=*/ null)
|
||||
.getResults();
|
||||
assertThat(page).hasSize(2);
|
||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
|
||||
@@ -1297,7 +1319,8 @@ public class AppSearchImplTest {
|
||||
.setRankingStrategy(
|
||||
SearchSpec
|
||||
.RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP)
|
||||
.build())
|
||||
.build(),
|
||||
/*logger=*/ null)
|
||||
.getResults();
|
||||
assertThat(page).hasSize(2);
|
||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
|
||||
@@ -1499,7 +1522,9 @@ public class AppSearchImplTest {
|
||||
mTemporaryFolder.newFolder(),
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ "");
|
||||
/*globalQuerierPackage=*/ "",
|
||||
/*logger
|
||||
=*/ null);
|
||||
|
||||
// Initial check that we could do something at first.
|
||||
List<AppSearchSchema> schemas =
|
||||
@@ -1561,7 +1586,8 @@ public class AppSearchImplTest {
|
||||
"query",
|
||||
new SearchSpec.Builder()
|
||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||
.build());
|
||||
.build(),
|
||||
/*logger=*/ null);
|
||||
});
|
||||
|
||||
expectThrows(
|
||||
@@ -1573,7 +1599,8 @@ public class AppSearchImplTest {
|
||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||
.build(),
|
||||
"package",
|
||||
/*callerUid=*/ 1);
|
||||
/*callerUid=*/ 1,
|
||||
/*logger=*/ null);
|
||||
});
|
||||
|
||||
expectThrows(
|
||||
@@ -1647,7 +1674,8 @@ public class AppSearchImplTest {
|
||||
appsearchDir,
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ "");
|
||||
/*globalQuerierPackage=*/ "",
|
||||
/*logger=*/ null);
|
||||
|
||||
List<AppSearchSchema> schemas =
|
||||
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||
@@ -1677,7 +1705,8 @@ public class AppSearchImplTest {
|
||||
appsearchDir,
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ "");
|
||||
/*globalQuerierPackage=*/ "",
|
||||
/*logger=*/ null);
|
||||
getResult =
|
||||
appSearchImpl2.getDocument(
|
||||
"package", "database", "namespace1", "id1", Collections.emptyMap());
|
||||
@@ -1694,7 +1723,8 @@ public class AppSearchImplTest {
|
||||
appsearchDir,
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ "");
|
||||
/*globalQuerierPackage=*/ "",
|
||||
/*logger=*/ null);
|
||||
|
||||
List<AppSearchSchema> schemas =
|
||||
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||
@@ -1748,7 +1778,8 @@ public class AppSearchImplTest {
|
||||
appsearchDir,
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ "");
|
||||
/*globalQuerierPackage=*/ "",
|
||||
/*logger=*/ null);
|
||||
expectThrows(
|
||||
AppSearchException.class,
|
||||
() ->
|
||||
@@ -1774,7 +1805,8 @@ public class AppSearchImplTest {
|
||||
appsearchDir,
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ "");
|
||||
/*globalQuerierPackage=*/ "",
|
||||
/*logger=*/ null);
|
||||
|
||||
List<AppSearchSchema> schemas =
|
||||
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||
@@ -1835,7 +1867,8 @@ public class AppSearchImplTest {
|
||||
appsearchDir,
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ "");
|
||||
/*globalQuerierPackage=*/ "",
|
||||
/*logger=*/ null);
|
||||
expectThrows(
|
||||
AppSearchException.class,
|
||||
() ->
|
||||
|
||||
@@ -23,13 +23,21 @@ import android.annotation.Nullable;
|
||||
import android.app.appsearch.AppSearchResult;
|
||||
import android.app.appsearch.AppSearchSchema;
|
||||
import android.app.appsearch.GenericDocument;
|
||||
import android.app.appsearch.SearchResultPage;
|
||||
import android.app.appsearch.SearchSpec;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||
import com.android.server.appsearch.proto.InitializeStatsProto;
|
||||
import com.android.server.appsearch.proto.PutDocumentStatsProto;
|
||||
import com.android.server.appsearch.proto.QueryStatsProto;
|
||||
import com.android.server.appsearch.proto.ScoringSpecProto;
|
||||
import com.android.server.appsearch.proto.TermMatchType;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@@ -54,23 +62,93 @@ public class AppSearchLoggerTest {
|
||||
mTemporaryFolder.newFolder(),
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ context.getPackageName());
|
||||
/*globalQuerierPackage=*/ context.getPackageName(),
|
||||
/*logger=*/ null);
|
||||
mLogger = new TestLogger();
|
||||
}
|
||||
|
||||
// Test only not thread safe.
|
||||
public class TestLogger implements AppSearchLogger {
|
||||
@Nullable CallStats mCallStats;
|
||||
@Nullable PutDocumentStats mPutDocumentStats;
|
||||
@Nullable InitializeStats mInitializeStats;
|
||||
@Nullable SearchStats mSearchStats;
|
||||
|
||||
@Override
|
||||
public void logStats(@NonNull CallStats stats) {
|
||||
throw new UnsupportedOperationException();
|
||||
mCallStats = stats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logStats(@NonNull PutDocumentStats stats) {
|
||||
mPutDocumentStats = stats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logStats(@NonNull InitializeStats stats) {
|
||||
mInitializeStats = stats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logStats(@NonNull SearchStats stats) {
|
||||
mSearchStats = stats;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppSearchLoggerHelper_testCopyNativeStats_initialize() {
|
||||
int nativeLatencyMillis = 3;
|
||||
int nativeDocumentStoreRecoveryCause = InitializeStatsProto.RecoveryCause.DATA_LOSS_VALUE;
|
||||
int nativeIndexRestorationCause =
|
||||
InitializeStatsProto.RecoveryCause.INCONSISTENT_WITH_GROUND_TRUTH_VALUE;
|
||||
int nativeSchemaStoreRecoveryCause =
|
||||
InitializeStatsProto.RecoveryCause.TOTAL_CHECKSUM_MISMATCH_VALUE;
|
||||
int nativeDocumentStoreRecoveryLatencyMillis = 7;
|
||||
int nativeIndexRestorationLatencyMillis = 8;
|
||||
int nativeSchemaStoreRecoveryLatencyMillis = 9;
|
||||
int nativeDocumentStoreDataStatus =
|
||||
InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE;
|
||||
int nativeNumDocuments = 11;
|
||||
int nativeNumSchemaTypes = 12;
|
||||
InitializeStatsProto.Builder nativeInitBuilder =
|
||||
InitializeStatsProto.newBuilder()
|
||||
.setLatencyMs(nativeLatencyMillis)
|
||||
.setDocumentStoreRecoveryCause(
|
||||
InitializeStatsProto.RecoveryCause.forNumber(
|
||||
nativeDocumentStoreRecoveryCause))
|
||||
.setIndexRestorationCause(
|
||||
InitializeStatsProto.RecoveryCause.forNumber(
|
||||
nativeIndexRestorationCause))
|
||||
.setSchemaStoreRecoveryCause(
|
||||
InitializeStatsProto.RecoveryCause.forNumber(
|
||||
nativeSchemaStoreRecoveryCause))
|
||||
.setDocumentStoreRecoveryLatencyMs(nativeDocumentStoreRecoveryLatencyMillis)
|
||||
.setIndexRestorationLatencyMs(nativeIndexRestorationLatencyMillis)
|
||||
.setSchemaStoreRecoveryLatencyMs(nativeSchemaStoreRecoveryLatencyMillis)
|
||||
.setDocumentStoreDataStatus(
|
||||
InitializeStatsProto.DocumentStoreDataStatus.forNumber(
|
||||
nativeDocumentStoreDataStatus))
|
||||
.setNumDocuments(nativeNumDocuments)
|
||||
.setNumSchemaTypes(nativeNumSchemaTypes);
|
||||
InitializeStats.Builder initBuilder = new InitializeStats.Builder();
|
||||
|
||||
AppSearchLoggerHelper.copyNativeStats(nativeInitBuilder.build(), initBuilder);
|
||||
|
||||
InitializeStats iStats = initBuilder.build();
|
||||
assertThat(iStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
|
||||
assertThat(iStats.getDocumentStoreRecoveryCause())
|
||||
.isEqualTo(nativeDocumentStoreRecoveryCause);
|
||||
assertThat(iStats.getIndexRestorationCause()).isEqualTo(nativeIndexRestorationCause);
|
||||
assertThat(iStats.getSchemaStoreRecoveryCause()).isEqualTo(nativeSchemaStoreRecoveryCause);
|
||||
assertThat(iStats.getDocumentStoreRecoveryLatencyMillis())
|
||||
.isEqualTo(nativeDocumentStoreRecoveryLatencyMillis);
|
||||
assertThat(iStats.getIndexRestorationLatencyMillis())
|
||||
.isEqualTo(nativeIndexRestorationLatencyMillis);
|
||||
assertThat(iStats.getSchemaStoreRecoveryLatencyMillis())
|
||||
.isEqualTo(nativeSchemaStoreRecoveryLatencyMillis);
|
||||
assertThat(iStats.getDocumentStoreDataStatus()).isEqualTo(nativeDocumentStoreDataStatus);
|
||||
assertThat(iStats.getDocumentCount()).isEqualTo(nativeNumDocuments);
|
||||
assertThat(iStats.getSchemaTypeCount()).isEqualTo(nativeNumSchemaTypes);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,9 +189,96 @@ public class AppSearchLoggerTest {
|
||||
assertThat(pStats.getNativeExceededMaxNumTokens()).isEqualTo(nativeExceededMaxNumTokens);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppSearchLoggerHelper_testCopyNativeStats_search() {
|
||||
int nativeLatencyMillis = 4;
|
||||
int nativeNumTerms = 5;
|
||||
// TODO(b/185804196) query length needs to be added in the native stats.
|
||||
// int nativeQueryLength = 6;
|
||||
int nativeNumNamespacesFiltered = 7;
|
||||
int nativeNumSchemaTypesFiltered = 8;
|
||||
int nativeRequestedPageSize = 9;
|
||||
int nativeNumResultsReturnedCurrentPage = 10;
|
||||
boolean nativeIsFirstPage = true;
|
||||
int nativeParseQueryLatencyMillis = 11;
|
||||
int nativeRankingStrategy = ScoringSpecProto.RankingStrategy.Code.CREATION_TIMESTAMP_VALUE;
|
||||
int nativeNumDocumentsScored = 13;
|
||||
int nativeScoringLatencyMillis = 14;
|
||||
int nativeRankingLatencyMillis = 15;
|
||||
int nativeNumResultsWithSnippets = 16;
|
||||
int nativeDocumentRetrievingLatencyMillis = 17;
|
||||
QueryStatsProto nativeQueryStats =
|
||||
QueryStatsProto.newBuilder()
|
||||
.setLatencyMs(nativeLatencyMillis)
|
||||
.setNumTerms(nativeNumTerms)
|
||||
.setNumNamespacesFiltered(nativeNumNamespacesFiltered)
|
||||
.setNumSchemaTypesFiltered(nativeNumSchemaTypesFiltered)
|
||||
.setRequestedPageSize(nativeRequestedPageSize)
|
||||
.setNumResultsReturnedCurrentPage(nativeNumResultsReturnedCurrentPage)
|
||||
.setIsFirstPage(nativeIsFirstPage)
|
||||
.setParseQueryLatencyMs(nativeParseQueryLatencyMillis)
|
||||
.setRankingStrategy(
|
||||
ScoringSpecProto.RankingStrategy.Code.forNumber(
|
||||
nativeRankingStrategy))
|
||||
.setNumDocumentsScored(nativeNumDocumentsScored)
|
||||
.setScoringLatencyMs(nativeScoringLatencyMillis)
|
||||
.setRankingLatencyMs(nativeRankingLatencyMillis)
|
||||
.setNumResultsWithSnippets(nativeNumResultsWithSnippets)
|
||||
.setDocumentRetrievalLatencyMs(nativeDocumentRetrievingLatencyMillis)
|
||||
.build();
|
||||
SearchStats.Builder qBuilder =
|
||||
new SearchStats.Builder(SearchStats.VISIBILITY_SCOPE_LOCAL, "packageName")
|
||||
.setDatabase("database");
|
||||
|
||||
AppSearchLoggerHelper.copyNativeStats(nativeQueryStats, qBuilder);
|
||||
|
||||
SearchStats sStats = qBuilder.build();
|
||||
assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
|
||||
assertThat(sStats.getTermCount()).isEqualTo(nativeNumTerms);
|
||||
// assertThat(sStats.getNativeQueryLength()).isEqualTo(nativeQueryLength);
|
||||
assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(nativeNumNamespacesFiltered);
|
||||
assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(nativeNumSchemaTypesFiltered);
|
||||
assertThat(sStats.getRequestedPageSize()).isEqualTo(nativeRequestedPageSize);
|
||||
assertThat(sStats.getCurrentPageReturnedResultCount())
|
||||
.isEqualTo(nativeNumResultsReturnedCurrentPage);
|
||||
assertThat(sStats.isFirstPage()).isTrue();
|
||||
assertThat(sStats.getParseQueryLatencyMillis()).isEqualTo(nativeParseQueryLatencyMillis);
|
||||
assertThat(sStats.getRankingStrategy()).isEqualTo(nativeRankingStrategy);
|
||||
assertThat(sStats.getScoredDocumentCount()).isEqualTo(nativeNumDocumentsScored);
|
||||
assertThat(sStats.getScoringLatencyMillis()).isEqualTo(nativeScoringLatencyMillis);
|
||||
assertThat(sStats.getRankingLatencyMillis()).isEqualTo(nativeRankingLatencyMillis);
|
||||
assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(nativeNumResultsWithSnippets);
|
||||
assertThat(sStats.getDocumentRetrievingLatencyMillis())
|
||||
.isEqualTo(nativeDocumentRetrievingLatencyMillis);
|
||||
}
|
||||
|
||||
//
|
||||
// Testing actual logging
|
||||
//
|
||||
@Test
|
||||
public void testLoggingStats_initialize() throws Exception {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
|
||||
AppSearchImpl appSearchImpl =
|
||||
AppSearchImpl.create(
|
||||
mTemporaryFolder.newFolder(),
|
||||
context,
|
||||
VisibilityStore.NO_OP_USER_ID,
|
||||
/*globalQuerierPackage=*/ context.getPackageName(),
|
||||
mLogger);
|
||||
|
||||
InitializeStats iStats = mLogger.mInitializeStats;
|
||||
assertThat(iStats).isNotNull();
|
||||
assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
|
||||
assertThat(iStats.getTotalLatencyMillis()).isGreaterThan(0);
|
||||
assertThat(iStats.hasDeSync()).isFalse();
|
||||
assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
|
||||
assertThat(iStats.getDocumentStoreDataStatus())
|
||||
.isEqualTo(InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
|
||||
assertThat(iStats.getDocumentCount()).isEqualTo(0);
|
||||
assertThat(iStats.getSchemaTypeCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoggingStats_putDocument() throws Exception {
|
||||
// Insert schema
|
||||
@@ -141,4 +306,53 @@ public class AppSearchLoggerTest {
|
||||
// The rest of native stats have been tested in testCopyNativeStats
|
||||
assertThat(pStats.getNativeDocumentSizeBytes()).isGreaterThan(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoggingStats_search() throws Exception {
|
||||
// Insert schema
|
||||
final String testPackageName = "testPackage";
|
||||
final String testDatabase = "testDatabase";
|
||||
List<AppSearchSchema> schemas =
|
||||
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||
mAppSearchImpl.setSchema(
|
||||
testPackageName,
|
||||
testDatabase,
|
||||
schemas,
|
||||
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
|
||||
/*schemasPackageAccessible=*/ Collections.emptyMap(),
|
||||
/*forceOverride=*/ false,
|
||||
/*version=*/ 0);
|
||||
GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
|
||||
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
|
||||
|
||||
// No query filters specified. package2 should only get its own documents back.
|
||||
SearchSpec searchSpec =
|
||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||
SearchResultPage searchResultPage =
|
||||
mAppSearchImpl.query(
|
||||
testPackageName,
|
||||
testDatabase,
|
||||
/*QueryExpression=*/ "",
|
||||
searchSpec,
|
||||
/*logger=*/ mLogger);
|
||||
|
||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
||||
|
||||
SearchStats sStats = mLogger.mSearchStats;
|
||||
|
||||
assertThat(sStats).isNotNull();
|
||||
assertThat(sStats.getPackageName()).isEqualTo(testPackageName);
|
||||
assertThat(sStats.getDatabase()).isEqualTo(testDatabase);
|
||||
assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
|
||||
assertThat(sStats.getTotalLatencyMillis()).isGreaterThan(0);
|
||||
assertThat(sStats.getVisibilityScope()).isEqualTo(SearchStats.VISIBILITY_SCOPE_LOCAL);
|
||||
assertThat(sStats.getTermCount()).isEqualTo(0);
|
||||
// assertThat(sStats.getNativeQueryLength()).isEqualTo(0);
|
||||
assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(1);
|
||||
assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(1);
|
||||
assertThat(sStats.getCurrentPageReturnedResultCount()).isEqualTo(1);
|
||||
assertThat(sStats.isFirstPage()).isTrue();
|
||||
assertThat(sStats.getScoredDocumentCount()).isEqualTo(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,4 +134,135 @@ public class AppSearchStatsTest {
|
||||
assertThat(pStats.getNativeNumTokensIndexed()).isEqualTo(nativeNumTokensIndexed);
|
||||
assertThat(pStats.getNativeExceededMaxNumTokens()).isEqualTo(nativeExceededMaxNumTokens);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppSearchStats_InitializeStats() {
|
||||
int prepareSchemaAndNamespacesLatencyMillis = 1;
|
||||
int prepareVisibilityFileLatencyMillis = 2;
|
||||
int nativeLatencyMillis = 3;
|
||||
int nativeDocumentStoreRecoveryCause = 4;
|
||||
int nativeIndexRestorationCause = 5;
|
||||
int nativeSchemaStoreRecoveryCause = 6;
|
||||
int nativeDocumentStoreRecoveryLatencyMillis = 7;
|
||||
int nativeIndexRestorationLatencyMillis = 8;
|
||||
int nativeSchemaStoreRecoveryLatencyMillis = 9;
|
||||
int nativeDocumentStoreDataStatus = 10;
|
||||
int nativeNumDocuments = 11;
|
||||
int nativeNumSchemaTypes = 12;
|
||||
|
||||
final InitializeStats.Builder iStatsBuilder =
|
||||
new InitializeStats.Builder()
|
||||
.setStatusCode(TEST_STATUS_CODE)
|
||||
.setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
|
||||
.setHasDeSync(/* hasDeSyncs= */ true)
|
||||
.setPrepareSchemaAndNamespacesLatencyMillis(
|
||||
prepareSchemaAndNamespacesLatencyMillis)
|
||||
.setPrepareVisibilityStoreLatencyMillis(prepareVisibilityFileLatencyMillis)
|
||||
.setNativeLatencyMillis(nativeLatencyMillis)
|
||||
.setDocumentStoreRecoveryCause(nativeDocumentStoreRecoveryCause)
|
||||
.setIndexRestorationCause(nativeIndexRestorationCause)
|
||||
.setSchemaStoreRecoveryCause(nativeSchemaStoreRecoveryCause)
|
||||
.setDocumentStoreRecoveryLatencyMillis(
|
||||
nativeDocumentStoreRecoveryLatencyMillis)
|
||||
.setIndexRestorationLatencyMillis(nativeIndexRestorationLatencyMillis)
|
||||
.setSchemaStoreRecoveryLatencyMillis(nativeSchemaStoreRecoveryLatencyMillis)
|
||||
.setDocumentStoreDataStatus(nativeDocumentStoreDataStatus)
|
||||
.setDocumentCount(nativeNumDocuments)
|
||||
.setSchemaTypeCount(nativeNumSchemaTypes);
|
||||
final InitializeStats iStats = iStatsBuilder.build();
|
||||
|
||||
assertThat(iStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
|
||||
assertThat(iStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
|
||||
assertThat(iStats.hasDeSync()).isTrue();
|
||||
assertThat(iStats.getPrepareSchemaAndNamespacesLatencyMillis())
|
||||
.isEqualTo(prepareSchemaAndNamespacesLatencyMillis);
|
||||
assertThat(iStats.getPrepareVisibilityStoreLatencyMillis())
|
||||
.isEqualTo(prepareVisibilityFileLatencyMillis);
|
||||
assertThat(iStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
|
||||
assertThat(iStats.getDocumentStoreRecoveryCause())
|
||||
.isEqualTo(nativeDocumentStoreRecoveryCause);
|
||||
assertThat(iStats.getIndexRestorationCause()).isEqualTo(nativeIndexRestorationCause);
|
||||
assertThat(iStats.getSchemaStoreRecoveryCause()).isEqualTo(nativeSchemaStoreRecoveryCause);
|
||||
assertThat(iStats.getDocumentStoreRecoveryLatencyMillis())
|
||||
.isEqualTo(nativeDocumentStoreRecoveryLatencyMillis);
|
||||
assertThat(iStats.getIndexRestorationLatencyMillis())
|
||||
.isEqualTo(nativeIndexRestorationLatencyMillis);
|
||||
assertThat(iStats.getSchemaStoreRecoveryLatencyMillis())
|
||||
.isEqualTo(nativeSchemaStoreRecoveryLatencyMillis);
|
||||
assertThat(iStats.getDocumentStoreDataStatus()).isEqualTo(nativeDocumentStoreDataStatus);
|
||||
assertThat(iStats.getDocumentCount()).isEqualTo(nativeNumDocuments);
|
||||
assertThat(iStats.getSchemaTypeCount()).isEqualTo(nativeNumSchemaTypes);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppSearchStats_SearchStats() {
|
||||
int rewriteSearchSpecLatencyMillis = 1;
|
||||
int rewriteSearchResultLatencyMillis = 2;
|
||||
int visibilityScope = SearchStats.VISIBILITY_SCOPE_LOCAL;
|
||||
int nativeLatencyMillis = 4;
|
||||
int nativeNumTerms = 5;
|
||||
int nativeQueryLength = 6;
|
||||
int nativeNumNamespacesFiltered = 7;
|
||||
int nativeNumSchemaTypesFiltered = 8;
|
||||
int nativeRequestedPageSize = 9;
|
||||
int nativeNumResultsReturnedCurrentPage = 10;
|
||||
boolean nativeIsFirstPage = true;
|
||||
int nativeParseQueryLatencyMillis = 11;
|
||||
int nativeRankingStrategy = 12;
|
||||
int nativeNumDocumentsScored = 13;
|
||||
int nativeScoringLatencyMillis = 14;
|
||||
int nativeRankingLatencyMillis = 15;
|
||||
int nativeNumResultsSnippeted = 16;
|
||||
int nativeDocumentRetrievingLatencyMillis = 17;
|
||||
final SearchStats.Builder sStatsBuilder =
|
||||
new SearchStats.Builder(visibilityScope, TEST_PACKAGE_NAME)
|
||||
.setDatabase(TEST_DATA_BASE)
|
||||
.setStatusCode(TEST_STATUS_CODE)
|
||||
.setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
|
||||
.setRewriteSearchSpecLatencyMillis(rewriteSearchSpecLatencyMillis)
|
||||
.setRewriteSearchResultLatencyMillis(rewriteSearchResultLatencyMillis)
|
||||
.setNativeLatencyMillis(nativeLatencyMillis)
|
||||
.setTermCount(nativeNumTerms)
|
||||
.setQueryLength(nativeQueryLength)
|
||||
.setFilteredNamespaceCount(nativeNumNamespacesFiltered)
|
||||
.setFilteredSchemaTypeCount(nativeNumSchemaTypesFiltered)
|
||||
.setRequestedPageSize(nativeRequestedPageSize)
|
||||
.setCurrentPageReturnedResultCount(nativeNumResultsReturnedCurrentPage)
|
||||
.setIsFirstPage(nativeIsFirstPage)
|
||||
.setParseQueryLatencyMillis(nativeParseQueryLatencyMillis)
|
||||
.setRankingStrategy(nativeRankingStrategy)
|
||||
.setScoredDocumentCount(nativeNumDocumentsScored)
|
||||
.setScoringLatencyMillis(nativeScoringLatencyMillis)
|
||||
.setRankingLatencyMillis(nativeRankingLatencyMillis)
|
||||
.setResultWithSnippetsCount(nativeNumResultsSnippeted)
|
||||
.setDocumentRetrievingLatencyMillis(nativeDocumentRetrievingLatencyMillis);
|
||||
final SearchStats sStats = sStatsBuilder.build();
|
||||
|
||||
assertThat(sStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
|
||||
assertThat(sStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
|
||||
assertThat(sStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
|
||||
assertThat(sStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
|
||||
assertThat(sStats.getRewriteSearchSpecLatencyMillis())
|
||||
.isEqualTo(rewriteSearchSpecLatencyMillis);
|
||||
assertThat(sStats.getRewriteSearchResultLatencyMillis())
|
||||
.isEqualTo(rewriteSearchResultLatencyMillis);
|
||||
assertThat(sStats.getVisibilityScope()).isEqualTo(visibilityScope);
|
||||
assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
|
||||
assertThat(sStats.getTermCount()).isEqualTo(nativeNumTerms);
|
||||
assertThat(sStats.getQueryLength()).isEqualTo(nativeQueryLength);
|
||||
assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(nativeNumNamespacesFiltered);
|
||||
assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(nativeNumSchemaTypesFiltered);
|
||||
assertThat(sStats.getRequestedPageSize()).isEqualTo(nativeRequestedPageSize);
|
||||
assertThat(sStats.getCurrentPageReturnedResultCount())
|
||||
.isEqualTo(nativeNumResultsReturnedCurrentPage);
|
||||
assertThat(sStats.isFirstPage()).isTrue();
|
||||
assertThat(sStats.getParseQueryLatencyMillis()).isEqualTo(nativeParseQueryLatencyMillis);
|
||||
assertThat(sStats.getRankingStrategy()).isEqualTo(nativeRankingStrategy);
|
||||
assertThat(sStats.getScoredDocumentCount()).isEqualTo(nativeNumDocumentsScored);
|
||||
assertThat(sStats.getScoringLatencyMillis()).isEqualTo(nativeScoringLatencyMillis);
|
||||
assertThat(sStats.getRankingLatencyMillis()).isEqualTo(nativeRankingLatencyMillis);
|
||||
assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(nativeNumResultsSnippeted);
|
||||
assertThat(sStats.getDocumentRetrievingLatencyMillis())
|
||||
.isEqualTo(nativeDocumentRetrievingLatencyMillis);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user