diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java index 138eb23148aff..72bb9f3d07c80 100644 --- a/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java +++ b/apex/appsearch/framework/java/external/android/app/appsearch/GenericDocument.java @@ -583,9 +583,9 @@ public class GenericDocument { * @param schemaType the {@link AppSearchSchema} type of the {@link GenericDocument}. The * provided {@code schemaType} must be defined using {@link AppSearchSession#setSchema} * prior to inserting a document of this {@code schemaType} into the AppSearch index - * using {@link AppSearchSession#put}. Otherwise, the document will - * be rejected by {@link AppSearchSession#put} with result code - * {@link AppSearchResult#RESULT_NOT_FOUND}. + * using {@link AppSearchSession#put}. Otherwise, the document will be rejected by + * {@link AppSearchSession#put} with result code {@link + * AppSearchResult#RESULT_NOT_FOUND}. */ @SuppressWarnings("unchecked") public Builder(@NonNull String uri, @NonNull String schemaType) { diff --git a/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java b/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java index 05b2128809628..57700f89403e6 100644 --- a/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java +++ b/apex/appsearch/framework/java/external/android/app/appsearch/PutDocumentsRequest.java @@ -28,9 +28,11 @@ import java.util.Collections; import java.util.List; /** - * Encapsulates a request to index a document into an {@link AppSearchSession} database. + * Encapsulates a request to index documents into an {@link AppSearchSession} database. * *
@see AppSearchSession#putDocuments
+ *
+ * @see AppSearchSession#put
*/
public final class PutDocumentsRequest {
private final List Any implementation needs to provide general information on how to log all the stats types.
+ * (e.g. {@link CallStats})
+ *
+ * All implementations of this interface must be thread safe.
+ *
+ * @hide
+ */
+public interface AppSearchLogger {
+ /** Logs {@link CallStats} */
+ void logStats(@NonNull CallStats stats) throws AppSearchException;
+
+ /** Logs {@link PutDocumentStats} */
+ void logStats(@NonNull PutDocumentStats stats) throws AppSearchException;
+
+ // TODO(b/173532925) Add remaining logStats once we add all the stats.
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchMigrationHelperImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchMigrationHelperImpl.java
index a501e99db1efe..a7f1cc4c793fa 100644
--- a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchMigrationHelperImpl.java
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/AppSearchMigrationHelperImpl.java
@@ -76,7 +76,7 @@ class AppSearchMigrationHelperImpl implements AppSearchMigrationHelper {
int currentVersion = mCurrentVersionMap.get(schemaType);
int finalVersion = mFinalVersionMap.get(schemaType);
try (FileOutputStream outputStream = new FileOutputStream(mFile)) {
- // TODO(b/177266929) change the output stream so that we can use it in platform
+ // TODO(b/151178558) change the output stream so that we can use it in platform
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream);
SearchResultPage searchResultPage =
mAppSearchImpl.query(
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java
new file mode 100644
index 0000000000000..81a5067c9fa19
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/CallStats.java
@@ -0,0 +1,200 @@
+/*
+ * 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 com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A class for setting basic information to log for all function calls.
+ *
+ * This class can set which stats to log for both batch and non-batch {@link
+ * android.app.appsearch.AppSearchSession} calls.
+ *
+ * Some function calls like {@link android.app.appsearch.AppSearchSession#setSchema} have their
+ * own detailed stats class {@link placeholder}. However, {@link CallStats} can still be used along
+ * with the detailed stats class for easy aggregation/analysis with other function calls.
+ *
+ * @hide
+ */
+public class CallStats {
+ @IntDef(
+ value = {
+ CALL_TYPE_UNKNOWN,
+ CALL_TYPE_INITIALIZE,
+ CALL_TYPE_SET_SCHEMA,
+ CALL_TYPE_PUT_DOCUMENTS,
+ CALL_TYPE_GET_DOCUMENTS,
+ CALL_TYPE_REMOVE_DOCUMENTS,
+ CALL_TYPE_PUT_DOCUMENT,
+ CALL_TYPE_GET_DOCUMENT,
+ CALL_TYPE_REMOVE_DOCUMENT,
+ CALL_TYPE_QUERY,
+ CALL_TYPE_OPTIMIZE,
+ CALL_TYPE_FLUSH,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CallType {}
+
+ public static final int CALL_TYPE_UNKNOWN = 0;
+ public static final int CALL_TYPE_INITIALIZE = 1;
+ public static final int CALL_TYPE_SET_SCHEMA = 2;
+ public static final int CALL_TYPE_PUT_DOCUMENTS = 3;
+ public static final int CALL_TYPE_GET_DOCUMENTS = 4;
+ public static final int CALL_TYPE_REMOVE_DOCUMENTS = 5;
+ public static final int CALL_TYPE_PUT_DOCUMENT = 6;
+ public static final int CALL_TYPE_GET_DOCUMENT = 7;
+ public static final int CALL_TYPE_REMOVE_DOCUMENT = 8;
+ public static final int CALL_TYPE_QUERY = 9;
+ public static final int CALL_TYPE_OPTIMIZE = 10;
+ public static final int CALL_TYPE_FLUSH = 11;
+
+ @NonNull private final GeneralStats mGeneralStats;
+ @CallType private final int mCallType;
+ private final int mEstimatedBinderLatencyMillis;
+ private final int mNumOperationsSucceeded;
+ private final int mNumOperationsFailed;
+
+ CallStats(@NonNull Builder builder) {
+ Preconditions.checkNotNull(builder);
+ mGeneralStats = Preconditions.checkNotNull(builder.mGeneralStats);
+ mCallType = builder.mCallType;
+ mEstimatedBinderLatencyMillis = builder.mEstimatedBinderLatencyMillis;
+ mNumOperationsSucceeded = builder.mNumOperationsSucceeded;
+ mNumOperationsFailed = builder.mNumOperationsFailed;
+ }
+
+ /** Returns general information for the call. */
+ @NonNull
+ public GeneralStats getGeneralStats() {
+ return mGeneralStats;
+ }
+
+ /** Returns type of the call. */
+ @CallType
+ public int getCallType() {
+ return mCallType;
+ }
+
+ /** Returns estimated binder latency, in milliseconds */
+ public int getEstimatedBinderLatencyMillis() {
+ return mEstimatedBinderLatencyMillis;
+ }
+
+ /**
+ * Returns number of operations succeeded.
+ *
+ * For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
+ * number of individual successful put operations. In this case, how many documents are
+ * successfully indexed.
+ *
+ * For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema}, the
+ * sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
+ * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
+ */
+ public int getNumOperationsSucceeded() {
+ return mNumOperationsSucceeded;
+ }
+
+ /**
+ * Returns number of operations failed.
+ *
+ * For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
+ * number of individual failed put operations. In this case, how many documents are failed to be
+ * indexed.
+ *
+ * For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema}, the
+ * sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
+ * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
+ */
+ public int getNumOperationsFailed() {
+ return mNumOperationsFailed;
+ }
+
+ /** Builder for {@link CallStats}. */
+ public static class Builder {
+ @NonNull final GeneralStats mGeneralStats;
+ @CallType int mCallType;
+ int mEstimatedBinderLatencyMillis;
+ int mNumOperationsSucceeded;
+ int mNumOperationsFailed;
+
+ /** Builder takes {@link GeneralStats} to hold general stats. */
+ public Builder(@NonNull GeneralStats generalStats) {
+ mGeneralStats = Preconditions.checkNotNull(generalStats);
+ }
+
+ /** Sets type of the call. */
+ @NonNull
+ public Builder setCallType(@CallType int callType) {
+ mCallType = callType;
+ return this;
+ }
+
+ /** Sets estimated binder latency, in milliseconds. */
+ @NonNull
+ public Builder setEstimatedBinderLatencyMillis(int estimatedBinderLatencyMillis) {
+ mEstimatedBinderLatencyMillis = estimatedBinderLatencyMillis;
+ return this;
+ }
+
+ /**
+ * Sets number of operations succeeded.
+ *
+ * For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
+ * number of individual successful put operations. In this case, how many documents are
+ * successfully indexed.
+ *
+ * For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema},
+ * the sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
+ * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
+ */
+ @NonNull
+ public Builder setNumOperationsSucceeded(int numOperationsSucceeded) {
+ mNumOperationsSucceeded = numOperationsSucceeded;
+ return this;
+ }
+
+ /**
+ * Sets number of operations failed.
+ *
+ * For example, for {@link android.app.appsearch.AppSearchSession#put}, it is the total
+ * number of individual failed put operations. In this case, how many documents are failed
+ * to be indexed.
+ *
+ * For non-batch calls such as {@link android.app.appsearch.AppSearchSession#setSchema},
+ * the sum of {@link CallStats#getNumOperationsSucceeded()} and {@link
+ * CallStats#getNumOperationsFailed()} is always 1 since there is only one operation.
+ */
+ @NonNull
+ public Builder setNumOperationsFailed(int numOperationsFailed) {
+ mNumOperationsFailed = numOperationsFailed;
+ return this;
+ }
+
+ /** Creates {@link CallStats} object from {@link Builder} instance. */
+ @NonNull
+ public CallStats build() {
+ return new CallStats(/* builder= */ this);
+ }
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/GeneralStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/GeneralStats.java
new file mode 100644
index 0000000000000..d2a45d5304f95
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/GeneralStats.java
@@ -0,0 +1,122 @@
+/*
+ * 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.NonNull;
+import android.app.appsearch.AppSearchResult;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class for holding general logging information.
+ *
+ * This class cannot be logged by {@link
+ * com.android.server.appsearch.external.localstorage.AppSearchLogger} directly. It is used for
+ * defining general logging information that is shared across different stats classes.
+ *
+ * @see PutDocumentStats
+ * @see CallStats
+ * @hide
+ */
+public final class GeneralStats {
+ /** Package name of the application. */
+ @NonNull private final String mPackageName;
+
+ /** Database name within AppSearch. */
+ @NonNull 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;
+
+ GeneralStats(@NonNull Builder builder) {
+ Preconditions.checkNotNull(builder);
+ mPackageName = Preconditions.checkNotNull(builder.mPackageName);
+ mDatabase = Preconditions.checkNotNull(builder.mDatabase);
+ mStatusCode = builder.mStatusCode;
+ mTotalLatencyMillis = builder.mTotalLatencyMillis;
+ }
+
+ /** Returns package name. */
+ @NonNull
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ /** Returns database name. */
+ @NonNull
+ public String getDatabase() {
+ return mDatabase;
+ }
+
+ /** Returns result code from {@link AppSearchResult#getResultCode()} */
+ @AppSearchResult.ResultCode
+ public int getStatusCode() {
+ return mStatusCode;
+ }
+
+ /** Returns total latency, in milliseconds. */
+ public int getTotalLatencyMillis() {
+ return mTotalLatencyMillis;
+ }
+
+ /** Builder for {@link GeneralStats}. */
+ public static class Builder {
+ @NonNull final String mPackageName;
+ @NonNull final String mDatabase;
+ @AppSearchResult.ResultCode int mStatusCode;
+ int mTotalLatencyMillis;
+
+ /**
+ * Constructor
+ *
+ * @param packageName name of the package logging stats
+ * @param dataBase name of the database logging stats
+ */
+ public Builder(@NonNull String packageName, @NonNull String dataBase) {
+ mPackageName = Preconditions.checkNotNull(packageName);
+ mDatabase = Preconditions.checkNotNull(dataBase);
+ }
+
+ /** Sets status code returned from {@link AppSearchResult#getResultCode()} */
+ @NonNull
+ public Builder setStatusCode(@AppSearchResult.ResultCode int statusCode) {
+ mStatusCode = statusCode;
+ return this;
+ }
+
+ /** Sets total latency, in milliseconds. */
+ @NonNull
+ public Builder setTotalLatencyMillis(int totalLatencyMillis) {
+ mTotalLatencyMillis = totalLatencyMillis;
+ return this;
+ }
+
+ /**
+ * Creates a new {@link GeneralStats} object from the contents of this {@link Builder}
+ * instance.
+ */
+ @NonNull
+ public GeneralStats build() {
+ return new GeneralStats(/* builder= */ this);
+ }
+ }
+}
diff --git a/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java
new file mode 100644
index 0000000000000..b1b643b668598
--- /dev/null
+++ b/apex/appsearch/service/java/com/android/server/appsearch/external/localstorage/stats/PutDocumentStats.java
@@ -0,0 +1,219 @@
+/*
+ * 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.NonNull;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A class for holding detailed stats to log for each individual document put by a {@link
+ * android.app.appsearch.AppSearchSession#put} call.
+ *
+ * @hide
+ */
+public final class PutDocumentStats {
+ /** {@link GeneralStats} holds the general stats. */
+ @NonNull private final GeneralStats mGeneralStats;
+
+ /** Time used to generate a document proto from a Bundle. */
+ private final int mGenerateDocumentProtoLatencyMillis;
+
+ /** Time used to rewrite types and namespaces in the document. */
+ private final int mRewriteDocumentTypesLatencyMillis;
+
+ /** Overall time used for the native function call. */
+ private final int mNativeLatencyMillis;
+
+ /** Time used to store the document. */
+ private final int mNativeDocumentStoreLatencyMillis;
+
+ /** Time used to index the document. It doesn't include the time to merge indices. */
+ private final int mNativeIndexLatencyMillis;
+
+ /** Time used to merge the indices. */
+ private final int mNativeIndexMergeLatencyMillis;
+
+ /** Document size in bytes. */
+ private final int mNativeDocumentSizeBytes;
+
+ /** Number of tokens added to the index. */
+ private final int mNativeNumTokensIndexed;
+
+ /** Number of tokens clipped for exceeding the max number. */
+ private final int mNativeNumTokensClipped;
+
+ PutDocumentStats(@NonNull Builder builder) {
+ Preconditions.checkNotNull(builder);
+ mGeneralStats = Preconditions.checkNotNull(builder.mGeneralStats);
+ mGenerateDocumentProtoLatencyMillis = builder.mGenerateDocumentProtoLatencyMillis;
+ mRewriteDocumentTypesLatencyMillis = builder.mRewriteDocumentTypesLatencyMillis;
+ mNativeLatencyMillis = builder.mNativeLatencyMillis;
+ mNativeDocumentStoreLatencyMillis = builder.mNativeDocumentStoreLatencyMillis;
+ mNativeIndexLatencyMillis = builder.mNativeIndexLatencyMillis;
+ mNativeIndexMergeLatencyMillis = builder.mNativeIndexMergeLatencyMillis;
+ mNativeDocumentSizeBytes = builder.mNativeDocumentSizeBytes;
+ mNativeNumTokensIndexed = builder.mNativeNumTokensIndexed;
+ mNativeNumTokensClipped = builder.mNativeNumTokensClipped;
+ }
+
+ /** Returns the {@link GeneralStats} object attached to this instance. */
+ @NonNull
+ public GeneralStats getGeneralStats() {
+ return mGeneralStats;
+ }
+
+ /** Returns time spent on generating document proto, in milliseconds. */
+ public int getGenerateDocumentProtoLatencyMillis() {
+ return mGenerateDocumentProtoLatencyMillis;
+ }
+
+ /** Returns time spent on rewriting types and namespaces in document, in milliseconds. */
+ public int getRewriteDocumentTypesLatencyMillis() {
+ return mRewriteDocumentTypesLatencyMillis;
+ }
+
+ /** Returns time spent in native, in milliseconds. */
+ public int getNativeLatencyMillis() {
+ return mNativeLatencyMillis;
+ }
+
+ /** Returns time spent on document store, in milliseconds. */
+ public int getNativeDocumentStoreLatencyMillis() {
+ return mNativeDocumentStoreLatencyMillis;
+ }
+
+ /** Returns time spent on indexing, in milliseconds. */
+ public int getNativeIndexLatencyMillis() {
+ return mNativeIndexLatencyMillis;
+ }
+
+ /** Returns time spent on merging indices, in milliseconds. */
+ public int getNativeIndexMergeLatencyMillis() {
+ return mNativeIndexMergeLatencyMillis;
+ }
+
+ /** Returns document size, in bytes. */
+ public int getNativeDocumentSizeBytes() {
+ return mNativeDocumentSizeBytes;
+ }
+
+ /** Returns number of tokens indexed. */
+ public int getNativeNumTokensIndexed() {
+ return mNativeNumTokensIndexed;
+ }
+
+ /** Returns number of tokens clipped for exceeding the max number. */
+ public int getNativeNumTokensClipped() {
+ return mNativeNumTokensClipped;
+ }
+
+ /** Builder for {@link PutDocumentStats}. */
+ public static class Builder {
+ @NonNull final GeneralStats mGeneralStats;
+ int mGenerateDocumentProtoLatencyMillis;
+ int mRewriteDocumentTypesLatencyMillis;
+ int mNativeLatencyMillis;
+ int mNativeDocumentStoreLatencyMillis;
+ int mNativeIndexLatencyMillis;
+ int mNativeIndexMergeLatencyMillis;
+ int mNativeDocumentSizeBytes;
+ int mNativeNumTokensIndexed;
+ int mNativeNumTokensClipped;
+
+ /** Builder takes {@link GeneralStats} to hold general stats. */
+ public Builder(@NonNull GeneralStats generalStats) {
+ mGeneralStats = Preconditions.checkNotNull(generalStats);
+ }
+
+ /** Sets how much time we spend for generating document proto, in milliseconds. */
+ @NonNull
+ public Builder setGenerateDocumentProtoLatencyMillis(
+ int generateDocumentProtoLatencyMillis) {
+ mGenerateDocumentProtoLatencyMillis = generateDocumentProtoLatencyMillis;
+ return this;
+ }
+
+ /**
+ * Sets how much time we spend for rewriting types and namespaces in document, in
+ * milliseconds.
+ */
+ @NonNull
+ public Builder setRewriteDocumentTypesLatencyMillis(int rewriteDocumentTypesLatencyMillis) {
+ mRewriteDocumentTypesLatencyMillis = rewriteDocumentTypesLatencyMillis;
+ return this;
+ }
+
+ /** Sets the native latency, in milliseconds. */
+ @NonNull
+ public Builder setNativeLatencyMillis(int nativeLatencyMillis) {
+ mNativeLatencyMillis = nativeLatencyMillis;
+ return this;
+ }
+
+ /** Sets how much time we spend on document store, in milliseconds. */
+ @NonNull
+ public Builder setNativeDocumentStoreLatencyMillis(int nativeDocumentStoreLatencyMillis) {
+ mNativeDocumentStoreLatencyMillis = nativeDocumentStoreLatencyMillis;
+ return this;
+ }
+
+ /** Sets the native index latency, in milliseconds. */
+ @NonNull
+ public Builder setNativeIndexLatencyMillis(int nativeIndexLatencyMillis) {
+ mNativeIndexLatencyMillis = nativeIndexLatencyMillis;
+ return this;
+ }
+
+ /** Sets how much time we spend on merging indices, in milliseconds. */
+ @NonNull
+ public Builder setNativeIndexMergeLatencyMillis(int nativeIndexMergeLatencyMillis) {
+ mNativeIndexMergeLatencyMillis = nativeIndexMergeLatencyMillis;
+ return this;
+ }
+
+ /** Sets document size, in bytes. */
+ @NonNull
+ public Builder setNativeDocumentSizeBytes(int nativeDocumentSizeBytes) {
+ mNativeDocumentSizeBytes = nativeDocumentSizeBytes;
+ return this;
+ }
+
+ /** Sets number of tokens indexed in native. */
+ @NonNull
+ public Builder setNativeNumTokensIndexed(int nativeNumTokensIndexed) {
+ mNativeNumTokensIndexed = nativeNumTokensIndexed;
+ return this;
+ }
+
+ /** Sets number of tokens clipped for exceeding the max number. */
+ @NonNull
+ public Builder setNativeNumTokensClipped(int nativeNumTokensClipped) {
+ mNativeNumTokensClipped = nativeNumTokensClipped;
+ return this;
+ }
+
+ /**
+ * Creates a new {@link PutDocumentStats} object from the contents of this {@link Builder}
+ * instance.
+ */
+ @NonNull
+ public PutDocumentStats build() {
+ return new PutDocumentStats(/* builder= */ this);
+ }
+ }
+}
diff --git a/apex/appsearch/synced_jetpack_changeid.txt b/apex/appsearch/synced_jetpack_changeid.txt
index d076db3b8f826..fc0299ef88af9 100644
--- a/apex/appsearch/synced_jetpack_changeid.txt
+++ b/apex/appsearch/synced_jetpack_changeid.txt
@@ -1 +1 @@
-Ia9a8daef1a6d7d9432f7808d440abd64f4797701
+I895f5fb3bcb4be0642c6193000e57d80aafe2166
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
index ea21e19b2bea2..34c7ccbd4df13 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/AppSearchSessionShim.java
@@ -90,11 +90,11 @@ public interface AppSearchSessionShim extends Closeable {
* It is a no-op to set the same schema as has been previously set; this is handled
* efficiently.
*
- * By default, documents are visible on platform surfaces. To opt out, call
- * {@link SetSchemaRequest.Builder#setSchemaTypeVisibilityForSystemUi} with {@code visible} as
- * false. Any visibility settings apply only to the schemas that are included in the
- * {@code request}. Visibility settings for a schema type do not persist across
- * {@link #setSchema} calls.
+ * By default, documents are visible on platform surfaces. To opt out, call {@code
+ * SetSchemaRequest.Builder#setPlatformSurfaceable} with {@code surfaceable} as false. Any
+ * visibility settings apply only to the schemas that are included in the {@code request}.
+ * Visibility settings for a schema type do not apply or persist across {@link
+ * SetSchemaRequest}s.
*
* Migration: make non-backwards-compatible changes will delete all stored documents in old
* schema. You can save your documents by setting {@link
@@ -118,6 +118,8 @@ public interface AppSearchSessionShim extends Closeable {
* @see android.app.appsearch.AppSearchSchema.Migrator
* @see android.app.appsearch.AppSearchMigrationHelper.Transformer
*/
+ // TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
+ // exposed.
@NonNull
ListenableFuture Each {@link GenericDocument}'s {@code schemaType} field must be set to the name of a
- * schema type previously registered via the {@link #setSchema} method.
+ * Each {@link GenericDocument} object must have a {@code schemaType} field set to an {@link
+ * AppSearchSchema} type that has been previously registered by calling the {@link #setSchema}
+ * method.
*
- * @param request {@link PutDocumentsRequest} containing documents to be indexed
- * @return The pending result of performing this operation. The keys of the returned {@link
- * AppSearchBatchResult} are the URIs of the input documents. The values are {@code null} if
- * they were successfully indexed, or a failed {@link AppSearchResult} otherwise.
+ * @param request containing documents to be indexed.
+ * @return a {@link ListenableFuture} which resolves to an {@link AppSearchBatchResult}. The
+ * keys of the returned {@link AppSearchBatchResult} are the URIs of the input documents.
+ * The values are either {@code null} if the corresponding document was successfully
+ * indexed, or a failed {@link AppSearchResult} otherwise.
*/
@NonNull
ListenableFuture This method is lightweight. The heavy work will be done in {@link
- * SearchResultsShim#getNextPage()}.
+ * SearchResultsShim#getNextPage}.
*
* @param queryExpression query string to search.
* @param searchSpec spec for setting document filters, adding projection, setting term match
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
index 31c934f8bb270..d912c08e7d5f8 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/GlobalSearchSessionShim.java
@@ -37,11 +37,11 @@ public interface GlobalSearchSessionShim extends Closeable {
* SetSchemaRequest.Builder#setSchemaTypeVisibilityForSystemUi}, or {@link
* SetSchemaRequest.Builder#setDocumentClassVisibilityForSystemUi} when building a schema.
*
- * See {@link AppSearchSessionShim#search(String, SearchSpec)} for a detailed explanation on
- * forming a query string.
+ * See {@link AppSearchSessionShim#search} for a detailed explanation on forming a query
+ * string.
*
* This method is lightweight. The heavy work will be done in {@link
- * SearchResultsShim#getNextPage()}.
+ * SearchResultsShim#getNextPage}.
*
* @param queryExpression query string to search.
* @param searchSpec spec for setting document filters, adding projection, setting term match
diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/SearchResultsShim.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/SearchResultsShim.java
index 328c65ca27278..38f61f83d24e0 100644
--- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/SearchResultsShim.java
+++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/external/SearchResultsShim.java
@@ -24,25 +24,29 @@ import java.io.Closeable;
import java.util.List;
/**
- * SearchResultsShim are a returned object from a query API.
+ * Encapsulates results of a search operation.
*
- * Each {@link SearchResult} contains a document and may contain other fields like snippets based
- * on request.
+ * Each {@link AppSearchSessionShim#search} operation returns a list of {@link SearchResult}
+ * objects, referred to as a "page", limited by the size configured by {@link
+ * SearchSpec.Builder#setResultCountPerPage}.
*
- * Should close this object after finish fetching results.
+ * To fetch a page of results, call {@link #getNextPage()}.
+ *
+ * All instances of {@link SearchResultsShim} must call {@link SearchResultsShim#close()} after
+ * the results are fetched.
*
* This class is not thread safe.
*/
public interface SearchResultsShim extends Closeable {
/**
- * Gets a whole page of {@link SearchResult}s.
+ * Retrieves the next page of {@link SearchResult} objects.
*
- * Re-call this method to get next page of {@link SearchResult}, until it returns an empty
- * list.
+ * The page size is configured by {@link SearchSpec.Builder#setResultCountPerPage}.
*
- * The page size is set by {@link SearchSpec.Builder#setResultCountPerPage}.
+ * Continue calling this method to access results until it returns an empty list, signifying
+ * there are no more results.
*
- * @return The pending result of performing this operation.
+ * @return a {@link ListenableFuture} which resolves to a list of {@link SearchResult} objects.
*/
@NonNull
ListenableFuture> getNextPage();
diff --git a/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
new file mode 100644
index 0000000000000..4308885faaadd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/appsearch/external/localstorage/stats/AppSearchStatsTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+
+public class AppSearchStatsTest {
+ static final String TEST_PACKAGE_NAME = "com.google.test";
+ static final String TEST_DATA_BASE = "testDataBase";
+ static final int TEST_STATUS_CODE = 2;
+ static final int TEST_TOTAL_LATENCY_MILLIS = 20;
+
+ @Test
+ public void testAppSearchStats_GeneralStats() {
+ final GeneralStats gStats =
+ new GeneralStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
+ .setStatusCode(TEST_STATUS_CODE)
+ .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
+ .build();
+
+ assertThat(gStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
+ assertThat(gStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
+ assertThat(gStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+ assertThat(gStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
+ }
+
+ @Test
+ public void testAppSearchStats_CallStats() {
+ final int estimatedBinderLatencyMillis = 1;
+ final int numOperationsSucceeded = 2;
+ final int numOperationsFailed = 3;
+
+ final GeneralStats gStats =
+ new GeneralStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
+ .setStatusCode(TEST_STATUS_CODE)
+ .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
+ .build();
+ final @CallStats.CallType int callType = CallStats.CALL_TYPE_PUT_DOCUMENTS;
+ final CallStats cStats =
+ new CallStats.Builder(gStats)
+ .setCallType(callType)
+ .setEstimatedBinderLatencyMillis(estimatedBinderLatencyMillis)
+ .setNumOperationsSucceeded(numOperationsSucceeded)
+ .setNumOperationsFailed(numOperationsFailed)
+ .build();
+
+ assertThat(cStats.getGeneralStats().getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
+ assertThat(cStats.getGeneralStats().getDatabase()).isEqualTo(TEST_DATA_BASE);
+ assertThat(cStats.getGeneralStats().getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+ assertThat(cStats.getGeneralStats().getTotalLatencyMillis())
+ .isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
+ assertThat(cStats.getEstimatedBinderLatencyMillis())
+ .isEqualTo(estimatedBinderLatencyMillis);
+ assertThat(cStats.getCallType()).isEqualTo(callType);
+ assertThat(cStats.getNumOperationsSucceeded()).isEqualTo(numOperationsSucceeded);
+ assertThat(cStats.getNumOperationsFailed()).isEqualTo(numOperationsFailed);
+ }
+
+ @Test
+ public void testAppSearchStats_PutDocumentStats() {
+ final int generateDocumentProtoLatencyMillis = 1;
+ final int rewriteDocumentTypesLatencyMillis = 2;
+ final int nativeLatencyMillis = 3;
+ final int nativeDocumentStoreLatencyMillis = 4;
+ final int nativeIndexLatencyMillis = 5;
+ final int nativeIndexMergeLatencyMillis = 6;
+ final int nativeDocumentSize = 7;
+ final int nativeNumTokensIndexed = 8;
+ final int nativeNumTokensClipped = 9;
+
+ final GeneralStats gStats =
+ new GeneralStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
+ .setStatusCode(TEST_STATUS_CODE)
+ .setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
+ .build();
+ final PutDocumentStats pStats =
+ new PutDocumentStats.Builder(gStats)
+ .setGenerateDocumentProtoLatencyMillis(generateDocumentProtoLatencyMillis)
+ .setRewriteDocumentTypesLatencyMillis(rewriteDocumentTypesLatencyMillis)
+ .setNativeLatencyMillis(nativeLatencyMillis)
+ .setNativeDocumentStoreLatencyMillis(nativeDocumentStoreLatencyMillis)
+ .setNativeIndexLatencyMillis(nativeIndexLatencyMillis)
+ .setNativeIndexMergeLatencyMillis(nativeIndexMergeLatencyMillis)
+ .setNativeDocumentSizeBytes(nativeDocumentSize)
+ .setNativeNumTokensIndexed(nativeNumTokensIndexed)
+ .setNativeNumTokensClipped(nativeNumTokensClipped)
+ .build();
+
+ assertThat(pStats.getGeneralStats().getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
+ assertThat(pStats.getGeneralStats().getDatabase()).isEqualTo(TEST_DATA_BASE);
+ assertThat(pStats.getGeneralStats().getStatusCode()).isEqualTo(TEST_STATUS_CODE);
+ assertThat(pStats.getGeneralStats().getTotalLatencyMillis())
+ .isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
+ assertThat(pStats.getGenerateDocumentProtoLatencyMillis())
+ .isEqualTo(generateDocumentProtoLatencyMillis);
+ assertThat(pStats.getRewriteDocumentTypesLatencyMillis())
+ .isEqualTo(rewriteDocumentTypesLatencyMillis);
+ assertThat(pStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
+ assertThat(pStats.getNativeDocumentStoreLatencyMillis())
+ .isEqualTo(nativeDocumentStoreLatencyMillis);
+ assertThat(pStats.getNativeIndexLatencyMillis()).isEqualTo(nativeIndexLatencyMillis);
+ assertThat(pStats.getNativeIndexMergeLatencyMillis())
+ .isEqualTo(nativeIndexMergeLatencyMillis);
+ assertThat(pStats.getNativeDocumentSizeBytes()).isEqualTo(nativeDocumentSize);
+ assertThat(pStats.getNativeNumTokensIndexed()).isEqualTo(nativeNumTokensIndexed);
+ assertThat(pStats.getNativeNumTokensClipped()).isEqualTo(nativeNumTokensClipped);
+ }
+}