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
|
* Returns a {@link Set} of deleted schema types.
|
||||||
* AppSearchSession#setSchema} call.
|
*
|
||||||
|
* <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
|
@NonNull
|
||||||
public Set<String> getDeletedTypes() {
|
public Set<String> getDeletedTypes() {
|
||||||
@@ -113,6 +118,15 @@ public class SetSchemaResponse {
|
|||||||
/**
|
/**
|
||||||
* Returns a {@link Set} of schema type that were migrated by the {@link
|
* Returns a {@link Set} of schema type that were migrated by the {@link
|
||||||
* AppSearchSession#setSchema} call.
|
* 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
|
@NonNull
|
||||||
public Set<String> getMigratedTypes() {
|
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.
|
* <p>If a {@link Migrator} is provided for this type and the migration is success triggered.
|
||||||
* The type will also appear in {@link #getMigratedTypes()}.
|
* The type will also appear in {@link #getMigratedTypes()}.
|
||||||
*
|
*
|
||||||
|
* @see SetSchemaRequest
|
||||||
* @see AppSearchSession#setSchema
|
* @see AppSearchSession#setSchema
|
||||||
* @see SetSchemaRequest.Builder#setForceOverride
|
* @see SetSchemaRequest.Builder#setForceOverride
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ public class AppSearchException extends Exception {
|
|||||||
* Initializes an {@link AppSearchException} with a result code and message.
|
* Initializes an {@link AppSearchException} with a result code and message.
|
||||||
*
|
*
|
||||||
* @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
|
* @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(
|
public AppSearchException(
|
||||||
@AppSearchResult.ResultCode int resultCode, @Nullable String message) {
|
@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.
|
* Initializes an {@link AppSearchException} with a result code, message and cause.
|
||||||
*
|
*
|
||||||
* @param resultCode One of the constants documented in {@link AppSearchResult#getResultCode}.
|
* @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(
|
public AppSearchException(
|
||||||
@AppSearchResult.ResultCode int resultCode,
|
@AppSearchResult.ResultCode int resultCode,
|
||||||
|
|||||||
@@ -501,7 +501,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
packageName,
|
packageName,
|
||||||
databaseName,
|
databaseName,
|
||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle));
|
new SearchSpec(searchSpecBundle),
|
||||||
|
/*logger=*/ null);
|
||||||
invokeCallbackOnResult(
|
invokeCallbackOnResult(
|
||||||
callback,
|
callback,
|
||||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||||
@@ -535,7 +536,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle),
|
new SearchSpec(searchSpecBundle),
|
||||||
packageName,
|
packageName,
|
||||||
callingUid);
|
callingUid,
|
||||||
|
/*logger=*/ null);
|
||||||
invokeCallbackOnResult(
|
invokeCallbackOnResult(
|
||||||
callback,
|
callback,
|
||||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||||
@@ -609,7 +611,8 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
packageName,
|
packageName,
|
||||||
databaseName,
|
databaseName,
|
||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle));
|
new SearchSpec(searchSpecBundle),
|
||||||
|
/*logger=*/ null);
|
||||||
while (!searchResultPage.getResults().isEmpty()) {
|
while (!searchResultPage.getResults().isEmpty()) {
|
||||||
for (int i = 0; i < searchResultPage.getResults().size(); i++) {
|
for (int i = 0; i < searchResultPage.getResults().size(); i++) {
|
||||||
AppSearchMigrationHelper.writeBundleToOutputStream(
|
AppSearchMigrationHelper.writeBundleToOutputStream(
|
||||||
|
|||||||
@@ -149,7 +149,8 @@ public final class ImplInstanceManager {
|
|||||||
private AppSearchImpl createImpl(@NonNull Context context, @UserIdInt int userId)
|
private AppSearchImpl createImpl(@NonNull Context context, @UserIdInt int userId)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
File appSearchDir = getAppSearchDir(userId);
|
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.SearchSpecToProtoConverter;
|
||||||
import com.android.server.appsearch.external.localstorage.converter.SetSchemaResponseToProtoConverter;
|
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.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.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
|
||||||
import com.google.android.icing.IcingSearchEngine;
|
import com.google.android.icing.IcingSearchEngine;
|
||||||
import com.google.android.icing.proto.DeleteByQueryResultProto;
|
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
|
* Creates and initializes an instance of {@link AppSearchImpl} which writes data to the given
|
||||||
* folder.
|
* 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
|
@NonNull
|
||||||
public static AppSearchImpl create(
|
public static AppSearchImpl create(
|
||||||
@NonNull File icingDir,
|
@NonNull File icingDir,
|
||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
int userId,
|
int userId,
|
||||||
@NonNull String globalQuerierPackage)
|
@NonNull String globalQuerierPackage,
|
||||||
|
@Nullable AppSearchLogger logger)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
Objects.requireNonNull(icingDir);
|
Objects.requireNonNull(icingDir);
|
||||||
Objects.requireNonNull(context);
|
Objects.requireNonNull(context);
|
||||||
Objects.requireNonNull(globalQuerierPackage);
|
Objects.requireNonNull(globalQuerierPackage);
|
||||||
|
|
||||||
|
long totalLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||||
|
InitializeStats.Builder initStatsBuilder = null;
|
||||||
|
if (logger != null) {
|
||||||
|
initStatsBuilder = new InitializeStats.Builder();
|
||||||
|
}
|
||||||
|
|
||||||
AppSearchImpl appSearchImpl =
|
AppSearchImpl appSearchImpl =
|
||||||
new AppSearchImpl(icingDir, context, userId, globalQuerierPackage);
|
new AppSearchImpl(
|
||||||
|
icingDir, context, userId, globalQuerierPackage, initStatsBuilder);
|
||||||
|
|
||||||
|
long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||||
appSearchImpl.initializeVisibilityStore();
|
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;
|
return appSearchImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @param initStatsBuilder collects stats for initialization if provided. */
|
||||||
private AppSearchImpl(
|
private AppSearchImpl(
|
||||||
@NonNull File icingDir,
|
@NonNull File icingDir,
|
||||||
@NonNull Context context,
|
@NonNull Context context,
|
||||||
int userId,
|
int userId,
|
||||||
@NonNull String globalQuerierPackage)
|
@NonNull String globalQuerierPackage,
|
||||||
|
@Nullable InitializeStats.Builder initStatsBuilder)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
mReadWriteLock.writeLock().lock();
|
mReadWriteLock.writeLock().lock();
|
||||||
|
|
||||||
@@ -211,13 +248,24 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
.setBaseDir(icingDir.getAbsolutePath())
|
.setBaseDir(icingDir.getAbsolutePath())
|
||||||
.build();
|
.build();
|
||||||
mIcingSearchEngineLocked = new IcingSearchEngine(options);
|
mIcingSearchEngineLocked = new IcingSearchEngine(options);
|
||||||
|
|
||||||
mVisibilityStoreLocked =
|
mVisibilityStoreLocked =
|
||||||
new VisibilityStore(this, context, userId, globalQuerierPackage);
|
new VisibilityStore(this, context, userId, globalQuerierPackage);
|
||||||
|
|
||||||
InitializeResultProto initializeResultProto = mIcingSearchEngineLocked.initialize();
|
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;
|
SchemaProto schemaProto;
|
||||||
GetAllNamespacesResultProto getAllNamespacesResultProto;
|
GetAllNamespacesResultProto getAllNamespacesResultProto = null;
|
||||||
try {
|
try {
|
||||||
checkSuccess(initializeResultProto.getStatus());
|
checkSuccess(initializeResultProto.getStatus());
|
||||||
schemaProto = getSchemaProtoLocked();
|
schemaProto = getSchemaProtoLocked();
|
||||||
@@ -225,6 +273,17 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
checkSuccess(getAllNamespacesResultProto.getStatus());
|
checkSuccess(getAllNamespacesResultProto.getStatus());
|
||||||
} catch (AppSearchException e) {
|
} catch (AppSearchException e) {
|
||||||
Log.w(TAG, "Error initializing, resetting IcingSearchEngine.", 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.
|
// Some error. Reset and see if it fixes it.
|
||||||
resetLocked();
|
resetLocked();
|
||||||
return;
|
return;
|
||||||
@@ -240,6 +299,14 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
for (String prefixedNamespace : getAllNamespacesResultProto.getNamespacesList()) {
|
for (String prefixedNamespace : getAllNamespacesResultProto.getNamespacesList()) {
|
||||||
addToMap(mNamespaceMapLocked, getPrefix(prefixedNamespace), prefixedNamespace);
|
addToMap(mNamespaceMapLocked, getPrefix(prefixedNamespace), prefixedNamespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// logging prepare_schema_and_namespaces latency
|
||||||
|
if (initStatsBuilder != null) {
|
||||||
|
initStatsBuilder.setPrepareSchemaAndNamespacesLatencyMillis(
|
||||||
|
(int)
|
||||||
|
(SystemClock.elapsedRealtime()
|
||||||
|
- prepareSchemaAndNamespacesLatencyStartMillis));
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
mReadWriteLock.writeLock().unlock();
|
mReadWriteLock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
@@ -539,7 +606,7 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
addToMap(mNamespaceMapLocked, prefix, documentBuilder.getNamespace());
|
addToMap(mNamespaceMapLocked, prefix, documentBuilder.getNamespace());
|
||||||
|
|
||||||
// Logging stats
|
// Logging stats
|
||||||
if (logger != null) {
|
if (logger != null && pStatsBuilder != null) {
|
||||||
pStatsBuilder
|
pStatsBuilder
|
||||||
.getGeneralStatsBuilder()
|
.getGeneralStatsBuilder()
|
||||||
.setStatusCode(
|
.setStatusCode(
|
||||||
@@ -562,7 +629,7 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
} finally {
|
} finally {
|
||||||
mReadWriteLock.writeLock().unlock();
|
mReadWriteLock.writeLock().unlock();
|
||||||
|
|
||||||
if (logger != null) {
|
if (logger != null && pStatsBuilder != null) {
|
||||||
long totalEndTimeMillis = SystemClock.elapsedRealtime();
|
long totalEndTimeMillis = SystemClock.elapsedRealtime();
|
||||||
pStatsBuilder
|
pStatsBuilder
|
||||||
.getGeneralStatsBuilder()
|
.getGeneralStatsBuilder()
|
||||||
@@ -644,6 +711,7 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
* @param databaseName The databaseName this query for.
|
* @param databaseName The databaseName this query for.
|
||||||
* @param queryExpression Query String to search.
|
* @param queryExpression Query String to search.
|
||||||
* @param searchSpec Spec for setting filters, raw query etc.
|
* @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
|
* @return The results of performing this search. It may contain an empty list of results if no
|
||||||
* documents matched the query.
|
* documents matched the query.
|
||||||
* @throws AppSearchException on IcingSearchEngine error.
|
* @throws AppSearchException on IcingSearchEngine error.
|
||||||
@@ -653,8 +721,17 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
@NonNull String packageName,
|
@NonNull String packageName,
|
||||||
@NonNull String databaseName,
|
@NonNull String databaseName,
|
||||||
@NonNull String queryExpression,
|
@NonNull String queryExpression,
|
||||||
@NonNull SearchSpec searchSpec)
|
@NonNull SearchSpec searchSpec,
|
||||||
|
@Nullable AppSearchLogger logger)
|
||||||
throws AppSearchException {
|
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();
|
mReadWriteLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
throwIfClosedLocked();
|
throwIfClosedLocked();
|
||||||
@@ -673,9 +750,15 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
Collections.singleton(createPrefix(packageName, databaseName)),
|
Collections.singleton(createPrefix(packageName, databaseName)),
|
||||||
allowedPrefixedSchemas,
|
allowedPrefixedSchemas,
|
||||||
queryExpression,
|
queryExpression,
|
||||||
searchSpec);
|
searchSpec,
|
||||||
|
sStatsBuilder);
|
||||||
} finally {
|
} finally {
|
||||||
mReadWriteLock.readLock().unlock();
|
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 searchSpec Spec for setting filters, raw query etc.
|
||||||
* @param callerPackageName Package name of the caller, should belong to the {@code callerUid}.
|
* @param callerPackageName Package name of the caller, should belong to the {@code callerUid}.
|
||||||
* @param callerUid UID of the client making the globalQuery call.
|
* @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
|
* @return The results of performing this search. It may contain an empty list of results if no
|
||||||
* documents matched the query.
|
* documents matched the query.
|
||||||
* @throws AppSearchException on IcingSearchEngine error.
|
* @throws AppSearchException on IcingSearchEngine error.
|
||||||
@@ -698,8 +782,16 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
@NonNull String queryExpression,
|
@NonNull String queryExpression,
|
||||||
@NonNull SearchSpec searchSpec,
|
@NonNull SearchSpec searchSpec,
|
||||||
@NonNull String callerPackageName,
|
@NonNull String callerPackageName,
|
||||||
int callerUid)
|
int callerUid,
|
||||||
|
@Nullable AppSearchLogger logger)
|
||||||
throws AppSearchException {
|
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();
|
mReadWriteLock.readLock().lock();
|
||||||
try {
|
try {
|
||||||
throwIfClosedLocked();
|
throwIfClosedLocked();
|
||||||
@@ -754,9 +846,19 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return doQueryLocked(
|
return doQueryLocked(
|
||||||
prefixFilters, allowedPrefixedSchemas, queryExpression, searchSpec);
|
prefixFilters,
|
||||||
|
allowedPrefixedSchemas,
|
||||||
|
queryExpression,
|
||||||
|
searchSpec,
|
||||||
|
sStatsBuilder);
|
||||||
} finally {
|
} finally {
|
||||||
mReadWriteLock.readLock().unlock();
|
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> prefixes,
|
||||||
@NonNull Set<String> allowedPrefixedSchemas,
|
@NonNull Set<String> allowedPrefixedSchemas,
|
||||||
@NonNull String queryExpression,
|
@NonNull String queryExpression,
|
||||||
@NonNull SearchSpec searchSpec)
|
@NonNull SearchSpec searchSpec,
|
||||||
|
@Nullable SearchStats.Builder sStatsBuilder)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
|
long rewriteSearchSpecLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||||
|
|
||||||
SearchSpecProto.Builder searchSpecBuilder =
|
SearchSpecProto.Builder searchSpecBuilder =
|
||||||
SearchSpecToProtoConverter.toSearchSpecProto(searchSpec).toBuilder()
|
SearchSpecToProtoConverter.toSearchSpecProto(searchSpec).toBuilder()
|
||||||
.setQuery(queryExpression);
|
.setQuery(queryExpression);
|
||||||
@@ -804,9 +909,17 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
// sending request to Icing.
|
// sending request to Icing.
|
||||||
if (!rewriteSearchSpecForPrefixesLocked(
|
if (!rewriteSearchSpecForPrefixesLocked(
|
||||||
searchSpecBuilder, prefixes, allowedPrefixedSchemas)) {
|
searchSpecBuilder, prefixes, allowedPrefixedSchemas)) {
|
||||||
|
if (sStatsBuilder != null) {
|
||||||
|
sStatsBuilder.setRewriteSearchSpecLatencyMillis(
|
||||||
|
(int)
|
||||||
|
(SystemClock.elapsedRealtime()
|
||||||
|
- rewriteSearchSpecLatencyStartMillis));
|
||||||
|
}
|
||||||
return new SearchResultPage(Bundle.EMPTY);
|
return new SearchResultPage(Bundle.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rewriteSearchSpec, rewriteResultSpec and convertScoringSpec are all counted in
|
||||||
|
// rewriteSearchSpecLatencyMillis
|
||||||
ResultSpecProto.Builder resultSpecBuilder =
|
ResultSpecProto.Builder resultSpecBuilder =
|
||||||
SearchSpecToProtoConverter.toResultSpecProto(searchSpec).toBuilder();
|
SearchSpecToProtoConverter.toResultSpecProto(searchSpec).toBuilder();
|
||||||
|
|
||||||
@@ -822,15 +935,38 @@ public final class AppSearchImpl implements Closeable {
|
|||||||
addPerNamespaceResultGroupingsLocked(
|
addPerNamespaceResultGroupingsLocked(
|
||||||
resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
|
resultSpecBuilder, prefixes, searchSpec.getResultGroupingLimit());
|
||||||
}
|
}
|
||||||
rewriteResultSpecForPrefixesLocked(resultSpecBuilder, prefixes, allowedPrefixedSchemas);
|
|
||||||
|
|
||||||
|
rewriteResultSpecForPrefixesLocked(resultSpecBuilder, prefixes, allowedPrefixedSchemas);
|
||||||
ScoringSpecProto scoringSpec = SearchSpecToProtoConverter.toScoringSpecProto(searchSpec);
|
ScoringSpecProto scoringSpec = SearchSpecToProtoConverter.toScoringSpecProto(searchSpec);
|
||||||
|
|
||||||
|
long rewriteSearchSpecLatencyEndMillis = SystemClock.elapsedRealtime();
|
||||||
|
|
||||||
SearchResultProto searchResultProto =
|
SearchResultProto searchResultProto =
|
||||||
mIcingSearchEngineLocked.search(
|
mIcingSearchEngineLocked.search(
|
||||||
searchSpecBuilder.build(), scoringSpec, resultSpecBuilder.build());
|
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());
|
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 android.app.appsearch.exceptions.AppSearchException;
|
||||||
|
|
||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
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.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface for implementing client-defined logging AppSearch operations stats.
|
* An interface for implementing client-defined logging AppSearch operations stats.
|
||||||
@@ -39,5 +41,11 @@ public interface AppSearchLogger {
|
|||||||
/** Logs {@link PutDocumentStats} */
|
/** Logs {@link PutDocumentStats} */
|
||||||
void logStats(@NonNull PutDocumentStats stats) throws AppSearchException;
|
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.
|
// 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 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.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.PutDocumentStatsProto;
|
||||||
|
import com.google.android.icing.proto.QueryStatsProto;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -35,7 +39,7 @@ public final class AppSearchLoggerHelper {
|
|||||||
private AppSearchLoggerHelper() {}
|
private AppSearchLoggerHelper() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies native stats to builder.
|
* Copies native PutDocument stats to builder.
|
||||||
*
|
*
|
||||||
* @param fromNativeStats stats copied from
|
* @param fromNativeStats stats copied from
|
||||||
* @param toStatsBuilder stats copied to
|
* @param toStatsBuilder stats copied to
|
||||||
@@ -56,4 +60,64 @@ public final class AppSearchLoggerHelper {
|
|||||||
.setNativeExceededMaxNumTokens(
|
.setNativeExceededMaxNumTokens(
|
||||||
fromNativeStats.getTokenizationStats().getExceededMaxTokenNum());
|
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.internal.util.FrameworkStatsLog;
|
||||||
import com.android.server.appsearch.external.localstorage.AppSearchLogger;
|
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.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.PutDocumentStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.MessageDigest;
|
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.
|
* Removes cached UID for package.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
I06df2c636d26419e653c5d8c9e7d15449da6816e
|
I19dac52031c47099f621eced9f148931f1021f25
|
||||||
|
|||||||
@@ -70,7 +70,8 @@ public class AppSearchImplPlatformTest {
|
|||||||
mTemporaryFolder.newFolder(),
|
mTemporaryFolder.newFolder(),
|
||||||
mContext,
|
mContext,
|
||||||
mContext.getUserId(),
|
mContext.getUserId(),
|
||||||
mContext.getPackageName());
|
mContext.getPackageName(),
|
||||||
|
/*logger=*/ null);
|
||||||
mGlobalQuerierUid =
|
mGlobalQuerierUid =
|
||||||
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
||||||
}
|
}
|
||||||
@@ -117,9 +118,8 @@ public class AppSearchImplPlatformTest {
|
|||||||
// No query filters specified, global query can retrieve all documents.
|
// No query filters specified, global query can retrieve all documents.
|
||||||
SearchSpec searchSpec =
|
SearchSpec searchSpec =
|
||||||
new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY).build();
|
new SearchSpec.Builder().setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY).build();
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
|
||||||
mAppSearchImpl.globalQuery(
|
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null);
|
||||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
|
|
||||||
assertThat(searchResultPage.getResults()).hasSize(2);
|
assertThat(searchResultPage.getResults()).hasSize(2);
|
||||||
|
|
||||||
// Document2 will be first since it got indexed later and has a "better", aka more recent
|
// 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)
|
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||||
.addFilterPackageNames("package1")
|
.addFilterPackageNames("package1")
|
||||||
.build();
|
.build();
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage = mAppSearchImpl.globalQuery(
|
||||||
mAppSearchImpl.globalQuery(
|
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null);
|
||||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
|
|
||||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
|
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document1);
|
||||||
|
|
||||||
@@ -186,9 +185,8 @@ public class AppSearchImplPlatformTest {
|
|||||||
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
.setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
|
||||||
.addFilterPackageNames("package2")
|
.addFilterPackageNames("package2")
|
||||||
.build();
|
.build();
|
||||||
searchResultPage =
|
searchResultPage = mAppSearchImpl.globalQuery(
|
||||||
mAppSearchImpl.globalQuery(
|
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid, /*logger=*/ null);
|
||||||
"", searchSpec, mContext.getPackageName(), mGlobalQuerierUid);
|
|
||||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
|
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ public class VisibilityStoreTest {
|
|||||||
mTemporaryFolder.newFolder(),
|
mTemporaryFolder.newFolder(),
|
||||||
mContext,
|
mContext,
|
||||||
mContext.getUserId(),
|
mContext.getUserId(),
|
||||||
/*globalQuerierPackage=*/ mContext.getPackageName());
|
/*globalQuerierPackage=*/ mContext.getPackageName(),
|
||||||
|
/*logger=*/ null);
|
||||||
mGlobalQuerierUid =
|
mGlobalQuerierUid =
|
||||||
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
||||||
|
|
||||||
@@ -163,7 +164,8 @@ public class VisibilityStoreTest {
|
|||||||
mTemporaryFolder.newFolder(),
|
mTemporaryFolder.newFolder(),
|
||||||
mContext,
|
mContext,
|
||||||
mContext.getUserId(),
|
mContext.getUserId(),
|
||||||
/*globalQuerierPackage=*/ mContext.getPackageName());
|
/*globalQuerierPackage=*/ mContext.getPackageName(),
|
||||||
|
/*logger=*/ null);
|
||||||
VisibilityStore visibilityStore = appSearchImpl.getVisibilityStoreLocked();
|
VisibilityStore visibilityStore = appSearchImpl.getVisibilityStoreLocked();
|
||||||
|
|
||||||
// Use some arbitrary callerUid. If we can't find the global querier's uid though,
|
// Use some arbitrary callerUid. If we can't find the global querier's uid though,
|
||||||
|
|||||||
@@ -82,7 +82,8 @@ public class AppSearchImplTest {
|
|||||||
mTemporaryFolder.newFolder(),
|
mTemporaryFolder.newFolder(),
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ context.getPackageName());
|
/*globalQuerierPackage=*/ context.getPackageName(),
|
||||||
|
/*logger=*/ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/175430168) add test to verify reset is working properly.
|
// TODO(b/175430168) add test to verify reset is working properly.
|
||||||
@@ -604,7 +605,7 @@ public class AppSearchImplTest {
|
|||||||
SearchSpec searchSpec =
|
SearchSpec searchSpec =
|
||||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage =
|
||||||
mAppSearchImpl.query("package", "EmptyDatabase", "", searchSpec);
|
mAppSearchImpl.query("package", "EmptyDatabase", "", searchSpec, /*logger=*/ null);
|
||||||
assertThat(searchResultPage.getResults()).isEmpty();
|
assertThat(searchResultPage.getResults()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -647,7 +648,7 @@ public class AppSearchImplTest {
|
|||||||
SearchSpec searchSpec =
|
SearchSpec searchSpec =
|
||||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage =
|
||||||
mAppSearchImpl.query("package2", "database2", "", searchSpec);
|
mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=*/ null);
|
||||||
assertThat(searchResultPage.getResults()).isEmpty();
|
assertThat(searchResultPage.getResults()).isEmpty();
|
||||||
|
|
||||||
// Insert package2 document
|
// Insert package2 document
|
||||||
@@ -655,7 +656,9 @@ public class AppSearchImplTest {
|
|||||||
mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
|
mAppSearchImpl.putDocument("package2", "database2", document, /*logger=*/ null);
|
||||||
|
|
||||||
// No query filters specified. package2 should only get its own documents back.
|
// 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()).hasSize(1);
|
||||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
||||||
}
|
}
|
||||||
@@ -703,7 +706,7 @@ public class AppSearchImplTest {
|
|||||||
.addFilterPackageNames("package1")
|
.addFilterPackageNames("package1")
|
||||||
.build();
|
.build();
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage =
|
||||||
mAppSearchImpl.query("package2", "database2", "", searchSpec);
|
mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=*/ null);
|
||||||
assertThat(searchResultPage.getResults()).isEmpty();
|
assertThat(searchResultPage.getResults()).isEmpty();
|
||||||
|
|
||||||
// Insert package2 document
|
// Insert package2 document
|
||||||
@@ -716,7 +719,9 @@ public class AppSearchImplTest {
|
|||||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||||
.addFilterPackageNames("package2")
|
.addFilterPackageNames("package2")
|
||||||
.build();
|
.build();
|
||||||
searchResultPage = mAppSearchImpl.query("package2", "database2", "", searchSpec);
|
searchResultPage =
|
||||||
|
mAppSearchImpl.query("package2", "database2", "", searchSpec, /*logger=
|
||||||
|
*/ null);
|
||||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
||||||
}
|
}
|
||||||
@@ -727,7 +732,11 @@ public class AppSearchImplTest {
|
|||||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage =
|
||||||
mAppSearchImpl.globalQuery(
|
mAppSearchImpl.globalQuery(
|
||||||
"", searchSpec, /*callerPackageName=*/ "", /*callerUid=*/ 0);
|
"",
|
||||||
|
searchSpec,
|
||||||
|
/*callerPackageName=*/ "",
|
||||||
|
/*callerUid=*/ 0,
|
||||||
|
/*logger=*/ null);
|
||||||
assertThat(searchResultPage.getResults()).isEmpty();
|
assertThat(searchResultPage.getResults()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1033,7 +1042,12 @@ public class AppSearchImplTest {
|
|||||||
SearchSpec searchSpec =
|
SearchSpec searchSpec =
|
||||||
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage =
|
||||||
mAppSearchImpl.query("package", "database", /*queryExpression=*/ "", searchSpec);
|
mAppSearchImpl.query(
|
||||||
|
"package",
|
||||||
|
"database",
|
||||||
|
/*queryExpression=*/ "",
|
||||||
|
searchSpec,
|
||||||
|
/*logger=*/ null);
|
||||||
assertThat(searchResultPage.getResults()).hasSize(1);
|
assertThat(searchResultPage.getResults()).hasSize(1);
|
||||||
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
|
||||||
|
|
||||||
@@ -1042,7 +1056,12 @@ public class AppSearchImplTest {
|
|||||||
|
|
||||||
// Verify the document is cleared.
|
// Verify the document is cleared.
|
||||||
searchResultPage =
|
searchResultPage =
|
||||||
mAppSearchImpl.query("package2", "database2", /*queryExpression=*/ "", searchSpec);
|
mAppSearchImpl.query(
|
||||||
|
"package2",
|
||||||
|
"database2",
|
||||||
|
/*queryExpression=*/ "",
|
||||||
|
searchSpec,
|
||||||
|
/*logger=*/ null);
|
||||||
assertThat(searchResultPage.getResults()).isEmpty();
|
assertThat(searchResultPage.getResults()).isEmpty();
|
||||||
|
|
||||||
// Verify the schema is cleared.
|
// Verify the schema is cleared.
|
||||||
@@ -1244,7 +1263,8 @@ public class AppSearchImplTest {
|
|||||||
new SearchSpec.Builder()
|
new SearchSpec.Builder()
|
||||||
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
||||||
.setRankingStrategy(SearchSpec.RANKING_STRATEGY_USAGE_COUNT)
|
.setRankingStrategy(SearchSpec.RANKING_STRATEGY_USAGE_COUNT)
|
||||||
.build())
|
.build(),
|
||||||
|
/*logger=*/ null)
|
||||||
.getResults();
|
.getResults();
|
||||||
assertThat(page).hasSize(2);
|
assertThat(page).hasSize(2);
|
||||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
|
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
|
||||||
@@ -1262,7 +1282,8 @@ public class AppSearchImplTest {
|
|||||||
.setRankingStrategy(
|
.setRankingStrategy(
|
||||||
SearchSpec
|
SearchSpec
|
||||||
.RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP)
|
.RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP)
|
||||||
.build())
|
.build(),
|
||||||
|
/*logger=*/ null)
|
||||||
.getResults();
|
.getResults();
|
||||||
assertThat(page).hasSize(2);
|
assertThat(page).hasSize(2);
|
||||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
|
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
|
||||||
@@ -1279,7 +1300,8 @@ public class AppSearchImplTest {
|
|||||||
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
.setTermMatch(SearchSpec.TERM_MATCH_EXACT_ONLY)
|
||||||
.setRankingStrategy(
|
.setRankingStrategy(
|
||||||
SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT)
|
SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT)
|
||||||
.build())
|
.build(),
|
||||||
|
/*logger=*/ null)
|
||||||
.getResults();
|
.getResults();
|
||||||
assertThat(page).hasSize(2);
|
assertThat(page).hasSize(2);
|
||||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
|
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id2");
|
||||||
@@ -1297,7 +1319,8 @@ public class AppSearchImplTest {
|
|||||||
.setRankingStrategy(
|
.setRankingStrategy(
|
||||||
SearchSpec
|
SearchSpec
|
||||||
.RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP)
|
.RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP)
|
||||||
.build())
|
.build(),
|
||||||
|
/*logger=*/ null)
|
||||||
.getResults();
|
.getResults();
|
||||||
assertThat(page).hasSize(2);
|
assertThat(page).hasSize(2);
|
||||||
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
|
assertThat(page.get(0).getGenericDocument().getId()).isEqualTo("id1");
|
||||||
@@ -1499,7 +1522,9 @@ public class AppSearchImplTest {
|
|||||||
mTemporaryFolder.newFolder(),
|
mTemporaryFolder.newFolder(),
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "");
|
/*globalQuerierPackage=*/ "",
|
||||||
|
/*logger
|
||||||
|
=*/ null);
|
||||||
|
|
||||||
// Initial check that we could do something at first.
|
// Initial check that we could do something at first.
|
||||||
List<AppSearchSchema> schemas =
|
List<AppSearchSchema> schemas =
|
||||||
@@ -1561,7 +1586,8 @@ public class AppSearchImplTest {
|
|||||||
"query",
|
"query",
|
||||||
new SearchSpec.Builder()
|
new SearchSpec.Builder()
|
||||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||||
.build());
|
.build(),
|
||||||
|
/*logger=*/ null);
|
||||||
});
|
});
|
||||||
|
|
||||||
expectThrows(
|
expectThrows(
|
||||||
@@ -1573,7 +1599,8 @@ public class AppSearchImplTest {
|
|||||||
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
|
||||||
.build(),
|
.build(),
|
||||||
"package",
|
"package",
|
||||||
/*callerUid=*/ 1);
|
/*callerUid=*/ 1,
|
||||||
|
/*logger=*/ null);
|
||||||
});
|
});
|
||||||
|
|
||||||
expectThrows(
|
expectThrows(
|
||||||
@@ -1647,7 +1674,8 @@ public class AppSearchImplTest {
|
|||||||
appsearchDir,
|
appsearchDir,
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "");
|
/*globalQuerierPackage=*/ "",
|
||||||
|
/*logger=*/ null);
|
||||||
|
|
||||||
List<AppSearchSchema> schemas =
|
List<AppSearchSchema> schemas =
|
||||||
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||||
@@ -1677,7 +1705,8 @@ public class AppSearchImplTest {
|
|||||||
appsearchDir,
|
appsearchDir,
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "");
|
/*globalQuerierPackage=*/ "",
|
||||||
|
/*logger=*/ null);
|
||||||
getResult =
|
getResult =
|
||||||
appSearchImpl2.getDocument(
|
appSearchImpl2.getDocument(
|
||||||
"package", "database", "namespace1", "id1", Collections.emptyMap());
|
"package", "database", "namespace1", "id1", Collections.emptyMap());
|
||||||
@@ -1694,7 +1723,8 @@ public class AppSearchImplTest {
|
|||||||
appsearchDir,
|
appsearchDir,
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "");
|
/*globalQuerierPackage=*/ "",
|
||||||
|
/*logger=*/ null);
|
||||||
|
|
||||||
List<AppSearchSchema> schemas =
|
List<AppSearchSchema> schemas =
|
||||||
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||||
@@ -1748,7 +1778,8 @@ public class AppSearchImplTest {
|
|||||||
appsearchDir,
|
appsearchDir,
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "");
|
/*globalQuerierPackage=*/ "",
|
||||||
|
/*logger=*/ null);
|
||||||
expectThrows(
|
expectThrows(
|
||||||
AppSearchException.class,
|
AppSearchException.class,
|
||||||
() ->
|
() ->
|
||||||
@@ -1774,7 +1805,8 @@ public class AppSearchImplTest {
|
|||||||
appsearchDir,
|
appsearchDir,
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "");
|
/*globalQuerierPackage=*/ "",
|
||||||
|
/*logger=*/ null);
|
||||||
|
|
||||||
List<AppSearchSchema> schemas =
|
List<AppSearchSchema> schemas =
|
||||||
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
Collections.singletonList(new AppSearchSchema.Builder("type").build());
|
||||||
@@ -1835,7 +1867,8 @@ public class AppSearchImplTest {
|
|||||||
appsearchDir,
|
appsearchDir,
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ "");
|
/*globalQuerierPackage=*/ "",
|
||||||
|
/*logger=*/ null);
|
||||||
expectThrows(
|
expectThrows(
|
||||||
AppSearchException.class,
|
AppSearchException.class,
|
||||||
() ->
|
() ->
|
||||||
|
|||||||
@@ -23,13 +23,21 @@ import android.annotation.Nullable;
|
|||||||
import android.app.appsearch.AppSearchResult;
|
import android.app.appsearch.AppSearchResult;
|
||||||
import android.app.appsearch.AppSearchSchema;
|
import android.app.appsearch.AppSearchSchema;
|
||||||
import android.app.appsearch.GenericDocument;
|
import android.app.appsearch.GenericDocument;
|
||||||
|
import android.app.appsearch.SearchResultPage;
|
||||||
|
import android.app.appsearch.SearchSpec;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
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.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.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.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@@ -54,23 +62,93 @@ public class AppSearchLoggerTest {
|
|||||||
mTemporaryFolder.newFolder(),
|
mTemporaryFolder.newFolder(),
|
||||||
context,
|
context,
|
||||||
VisibilityStore.NO_OP_USER_ID,
|
VisibilityStore.NO_OP_USER_ID,
|
||||||
/*globalQuerierPackage=*/ context.getPackageName());
|
/*globalQuerierPackage=*/ context.getPackageName(),
|
||||||
|
/*logger=*/ null);
|
||||||
mLogger = new TestLogger();
|
mLogger = new TestLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test only not thread safe.
|
// Test only not thread safe.
|
||||||
public class TestLogger implements AppSearchLogger {
|
public class TestLogger implements AppSearchLogger {
|
||||||
|
@Nullable CallStats mCallStats;
|
||||||
@Nullable PutDocumentStats mPutDocumentStats;
|
@Nullable PutDocumentStats mPutDocumentStats;
|
||||||
|
@Nullable InitializeStats mInitializeStats;
|
||||||
|
@Nullable SearchStats mSearchStats;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logStats(@NonNull CallStats stats) {
|
public void logStats(@NonNull CallStats stats) {
|
||||||
throw new UnsupportedOperationException();
|
mCallStats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void logStats(@NonNull PutDocumentStats stats) {
|
public void logStats(@NonNull PutDocumentStats stats) {
|
||||||
mPutDocumentStats = 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
|
@Test
|
||||||
@@ -111,9 +189,96 @@ public class AppSearchLoggerTest {
|
|||||||
assertThat(pStats.getNativeExceededMaxNumTokens()).isEqualTo(nativeExceededMaxNumTokens);
|
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
|
// 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
|
@Test
|
||||||
public void testLoggingStats_putDocument() throws Exception {
|
public void testLoggingStats_putDocument() throws Exception {
|
||||||
// Insert schema
|
// Insert schema
|
||||||
@@ -141,4 +306,53 @@ public class AppSearchLoggerTest {
|
|||||||
// The rest of native stats have been tested in testCopyNativeStats
|
// The rest of native stats have been tested in testCopyNativeStats
|
||||||
assertThat(pStats.getNativeDocumentSizeBytes()).isGreaterThan(0);
|
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.getNativeNumTokensIndexed()).isEqualTo(nativeNumTokensIndexed);
|
||||||
assertThat(pStats.getNativeExceededMaxNumTokens()).isEqualTo(nativeExceededMaxNumTokens);
|
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