Merge "Update framework from jetpack." into sc-dev

This commit is contained in:
Alexander Dorokhine
2021-06-22 17:30:26 +00:00
committed by Android (Google) Code Review
21 changed files with 843 additions and 313 deletions

View File

@@ -136,8 +136,6 @@ public final class AppSearchSession implements Closeable {
* @param callback Callback to receive errors resulting from setting the schema. If the
* operation succeeds, the callback will be invoked with {@code null}.
*/
// TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
// exposed.
public void setSchema(
@NonNull SetSchemaRequest request,
@NonNull Executor workExecutor,
@@ -152,7 +150,7 @@ public final class AppSearchSession implements Closeable {
for (AppSearchSchema schema : request.getSchemas()) {
schemaBundles.add(schema.getBundle());
}
Map<String, List<Bundle>> schemasPackageAccessibleBundles =
Map<String, List<Bundle>> schemasVisibleToPackagesBundles =
new ArrayMap<>(request.getSchemasVisibleToPackagesInternal().size());
for (Map.Entry<String, Set<PackageIdentifier>> entry :
request.getSchemasVisibleToPackagesInternal().entrySet()) {
@@ -160,7 +158,7 @@ public final class AppSearchSession implements Closeable {
for (PackageIdentifier packageIdentifier : entry.getValue()) {
packageIdentifierBundles.add(packageIdentifier.getBundle());
}
schemasPackageAccessibleBundles.put(entry.getKey(), packageIdentifierBundles);
schemasVisibleToPackagesBundles.put(entry.getKey(), packageIdentifierBundles);
}
// No need to trigger migration if user never set migrator
@@ -168,14 +166,14 @@ public final class AppSearchSession implements Closeable {
setSchemaNoMigrations(
request,
schemaBundles,
schemasPackageAccessibleBundles,
schemasVisibleToPackagesBundles,
callbackExecutor,
callback);
} else {
setSchemaWithMigrations(
request,
schemaBundles,
schemasPackageAccessibleBundles,
schemasVisibleToPackagesBundles,
workExecutor,
callbackExecutor,
callback);
@@ -704,7 +702,7 @@ public final class AppSearchSession implements Closeable {
private void setSchemaNoMigrations(
@NonNull SetSchemaRequest request,
@NonNull List<Bundle> schemaBundles,
@NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
@NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
@NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
try {
@@ -713,7 +711,7 @@ public final class AppSearchSession implements Closeable {
mDatabaseName,
schemaBundles,
new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
schemasPackageAccessibleBundles,
schemasVisibleToPackagesBundles,
request.isForceOverride(),
request.getVersion(),
mUserHandle,
@@ -761,7 +759,7 @@ public final class AppSearchSession implements Closeable {
private void setSchemaWithMigrations(
@NonNull SetSchemaRequest request,
@NonNull List<Bundle> schemaBundles,
@NonNull Map<String, List<Bundle>> schemasPackageAccessibleBundles,
@NonNull Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
@NonNull Executor workExecutor,
@NonNull @CallbackExecutor Executor callbackExecutor,
@NonNull Consumer<AppSearchResult<SetSchemaResponse>> callback) {
@@ -787,7 +785,7 @@ public final class AppSearchSession implements Closeable {
// No need to trigger migration if no migrator is active.
if (activeMigrators.isEmpty()) {
setSchemaNoMigrations(request, schemaBundles, schemasPackageAccessibleBundles,
setSchemaNoMigrations(request, schemaBundles, schemasVisibleToPackagesBundles,
callbackExecutor, callback);
return;
}
@@ -801,7 +799,7 @@ public final class AppSearchSession implements Closeable {
mDatabaseName,
schemaBundles,
new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
schemasPackageAccessibleBundles,
schemasVisibleToPackagesBundles,
/*forceOverride=*/ false,
request.getVersion(),
mUserHandle,
@@ -853,7 +851,7 @@ public final class AppSearchSession implements Closeable {
mDatabaseName,
schemaBundles,
new ArrayList<>(request.getSchemasNotDisplayedBySystem()),
schemasPackageAccessibleBundles,
schemasVisibleToPackagesBundles,
/*forceOverride=*/ true,
request.getVersion(),
mUserHandle,

View File

@@ -32,7 +32,7 @@ interface IAppSearchManager {
* @param schemaBundles List of {@link AppSearchSchema} bundles.
* @param schemasNotDisplayedBySystem Schema types that should not be surfaced on platform
* surfaces.
* @param schemasPackageAccessibleBundles Schema types that are visible to the specified
* @param schemasVisibleToPackagesBundles Schema types that are visible to the specified
* packages. The value List contains PackageIdentifier Bundles.
* @param forceOverride Whether to apply the new schema even if it is incompatible. All
* incompatible documents will be deleted.
@@ -48,7 +48,7 @@ interface IAppSearchManager {
in String databaseName,
in List<Bundle> schemaBundles,
in List<String> schemasNotDisplayedBySystem,
in Map<String, List<Bundle>> schemasPackageAccessibleBundles,
in Map<String, List<Bundle>> schemasVisibleToPackagesBundles,
boolean forceOverride,
in int schemaVersion,
in UserHandle userHandle,

View File

@@ -333,7 +333,7 @@ public class AppSearchManagerService extends SystemService {
for (int i = 0; i < schemaBundles.size(); i++) {
schemas.add(new AppSearchSchema(schemaBundles.get(i)));
}
Map<String, List<PackageIdentifier>> schemasPackageAccessible =
Map<String, List<PackageIdentifier>> schemasVisibleToPackages =
new ArrayMap<>(schemasVisibleToPackagesBundles.size());
for (Map.Entry<String, List<Bundle>> entry :
schemasVisibleToPackagesBundles.entrySet()) {
@@ -343,7 +343,7 @@ public class AppSearchManagerService extends SystemService {
packageIdentifiers.add(
new PackageIdentifier(entry.getValue().get(i)));
}
schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
schemasVisibleToPackages.put(entry.getKey(), packageIdentifiers);
}
instance = mAppSearchUserInstanceManager.getUserInstance(callingUser);
SetSchemaResponse setSchemaResponse = instance.getAppSearchImpl().setSchema(
@@ -352,7 +352,7 @@ public class AppSearchManagerService extends SystemService {
schemas,
instance.getVisibilityStore(),
schemasNotDisplayedBySystem,
schemasPackageAccessible,
schemasVisibleToPackages,
forceOverride,
schemaVersion);
++operationSuccessCount;

View File

@@ -346,11 +346,11 @@ public final class AppSearchImpl implements Closeable {
* @param packageName The package name that owns the schemas.
* @param databaseName The name of the database where this schema lives.
* @param schemas Schemas to set for this app.
* @param visibilityStore If set, {@code schemasNotPlatformSurfaceable} and {@code
* schemasPackageAccessible} will be saved here if the schema is successfully applied.
* @param schemasNotPlatformSurfaceable Schema types that should not be surfaced on platform
* @param visibilityStore If set, {@code schemasNotDisplayedBySystem} and {@code
* schemasVisibleToPackages} will be saved here if the schema is successfully applied.
* @param schemasNotDisplayedBySystem Schema types that should not be surfaced on platform
* surfaces.
* @param schemasPackageAccessible Schema types that are visible to the specified packages.
* @param schemasVisibleToPackages Schema types that are visible to the specified packages.
* @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents
* which do not comply with the new schema will be deleted.
* @param version The overall version number of the request.
@@ -366,8 +366,8 @@ public final class AppSearchImpl implements Closeable {
@NonNull String databaseName,
@NonNull List<AppSearchSchema> schemas,
@Nullable VisibilityStore visibilityStore,
@NonNull List<String> schemasNotPlatformSurfaceable,
@NonNull Map<String, List<PackageIdentifier>> schemasPackageAccessible,
@NonNull List<String> schemasNotDisplayedBySystem,
@NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages,
boolean forceOverride,
int version)
throws AppSearchException {
@@ -430,25 +430,25 @@ public final class AppSearchImpl implements Closeable {
}
if (visibilityStore != null) {
Set<String> prefixedSchemasNotPlatformSurfaceable =
new ArraySet<>(schemasNotPlatformSurfaceable.size());
for (int i = 0; i < schemasNotPlatformSurfaceable.size(); i++) {
prefixedSchemasNotPlatformSurfaceable.add(
prefix + schemasNotPlatformSurfaceable.get(i));
Set<String> prefixedSchemasNotDisplayedBySystem =
new ArraySet<>(schemasNotDisplayedBySystem.size());
for (int i = 0; i < schemasNotDisplayedBySystem.size(); i++) {
prefixedSchemasNotDisplayedBySystem.add(
prefix + schemasNotDisplayedBySystem.get(i));
}
Map<String, List<PackageIdentifier>> prefixedSchemasPackageAccessible =
new ArrayMap<>(schemasPackageAccessible.size());
Map<String, List<PackageIdentifier>> prefixedSchemasVisibleToPackages =
new ArrayMap<>(schemasVisibleToPackages.size());
for (Map.Entry<String, List<PackageIdentifier>> entry :
schemasPackageAccessible.entrySet()) {
prefixedSchemasPackageAccessible.put(prefix + entry.getKey(), entry.getValue());
schemasVisibleToPackages.entrySet()) {
prefixedSchemasVisibleToPackages.put(prefix + entry.getKey(), entry.getValue());
}
visibilityStore.setVisibility(
packageName,
databaseName,
prefixedSchemasNotPlatformSurfaceable,
prefixedSchemasPackageAccessible);
prefixedSchemasNotDisplayedBySystem,
prefixedSchemasVisibleToPackages);
}
return SetSchemaResponseToProtoConverter.toSetSchemaResponse(
@@ -737,6 +737,9 @@ public final class AppSearchImpl implements Closeable {
if (!filterPackageNames.isEmpty() && !filterPackageNames.contains(packageName)) {
// Client wanted to query over some packages that weren't its own. This isn't
// allowed through local query so we can return early with no results.
if (logger != null) {
sStatsBuilder.setStatusCode(AppSearchResult.RESULT_SECURITY_ERROR);
}
return new SearchResultPage(Bundle.EMPTY);
}
@@ -768,7 +771,7 @@ public final class AppSearchImpl implements Closeable {
* @param queryExpression Query String to search.
* @param searchSpec Spec for setting filters, raw query etc.
* @param callerPackageName Package name of the caller, should belong to the {@code
* userContext}.
* callerUserHandle}.
* @param visibilityStore Optional visibility store to obtain system and package visibility
* settings from
* @param callerUid UID of the client making the globalQuery call.
@@ -1465,7 +1468,6 @@ public final class AppSearchImpl implements Closeable {
mOptimizeIntervalCountLocked = 0;
mSchemaMapLocked.clear();
mNamespaceMapLocked.clear();
if (initStatsBuilder != null) {
initStatsBuilder
.setHasReset(true)

View File

@@ -0,0 +1,189 @@
/*
* 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.SetSchemaRequest;
import java.util.Objects;
/**
* Class holds detailed stats for Schema migration.
*
* @hide
*/
// TODO(b/173532925): Hides getter and setter functions for accessing {@code
// mFirstSetSchemaLatencyMillis} and {@code mSecondSetSchemaLatencyMillis} field.
public final class SchemaMigrationStats {
/** GetSchema latency in milliseconds. */
private final int mGetSchemaLatencyMillis;
/**
* Latency of querying all documents that need to be migrated to new version and transforming
* documents to new version in milliseconds.
*/
private final int mQueryAndTransformLatencyMillis;
private final int mFirstSetSchemaLatencyMillis;
private final int mSecondSetSchemaLatencyMillis;
/** Latency of putting migrated document to Icing lib in milliseconds. */
private final int mSaveDocumentLatencyMillis;
private final int mMigratedDocumentCount;
private final int mSavedDocumentCount;
SchemaMigrationStats(@NonNull Builder builder) {
Objects.requireNonNull(builder);
mGetSchemaLatencyMillis = builder.mGetSchemaLatencyMillis;
mQueryAndTransformLatencyMillis = builder.mQueryAndTransformLatencyMillis;
mFirstSetSchemaLatencyMillis = builder.mFirstSetSchemaLatencyMillis;
mSecondSetSchemaLatencyMillis = builder.mSecondSetSchemaLatencyMillis;
mSaveDocumentLatencyMillis = builder.mSaveDocumentLatencyMillis;
mMigratedDocumentCount = builder.mMigratedDocumentCount;
mSavedDocumentCount = builder.mSavedDocumentCount;
}
/** Returns GetSchema latency in milliseconds. */
public int getGetSchemaLatencyMillis() {
return mGetSchemaLatencyMillis;
}
/**
* Returns latency of querying all documents that need to be migrated to new version and
* transforming documents to new version in milliseconds.
*/
public int getQueryAndTransformLatencyMillis() {
return mQueryAndTransformLatencyMillis;
}
/**
* Returns latency of first SetSchema action in milliseconds.
*
* <p>If all schema fields are backward compatible, the schema will be successful set to Icing.
* Otherwise, we will retrieve incompatible types here.
*
* <p>Please see {@link SetSchemaRequest} for what is "incompatible".
*/
public int getFirstSetSchemaLatencyMillis() {
return mFirstSetSchemaLatencyMillis;
}
/**
* Returns latency of second SetSchema action in milliseconds.
*
* <p>If all schema fields are backward compatible, the schema will be successful set to Icing
* in the first setSchema action and this value will be 0. Otherwise, schema types will be set
* to Icing by this action.
*/
public int getSecondSetSchemaLatencyMillis() {
return mSecondSetSchemaLatencyMillis;
}
/** Returns latency of putting migrated document to Icing lib in milliseconds. */
public int getSaveDocumentLatencyMillis() {
return mSaveDocumentLatencyMillis;
}
/** Returns number of migrated documents. */
public int getMigratedDocumentCount() {
return mMigratedDocumentCount;
}
/** Returns number of updated documents which are saved in Icing lib. */
public int getSavedDocumentCount() {
return mSavedDocumentCount;
}
/** Builder for {@link SchemaMigrationStats}. */
public static class Builder {
int mGetSchemaLatencyMillis;
int mQueryAndTransformLatencyMillis;
int mFirstSetSchemaLatencyMillis;
int mSecondSetSchemaLatencyMillis;
int mSaveDocumentLatencyMillis;
int mMigratedDocumentCount;
int mSavedDocumentCount;
/** Sets latency for the GetSchema action in milliseconds. */
@NonNull
public SchemaMigrationStats.Builder setGetSchemaLatencyMillis(int getSchemaLatencyMillis) {
mGetSchemaLatencyMillis = getSchemaLatencyMillis;
return this;
}
/**
* Sets latency for querying all documents that need to be migrated to new version and
* transforming documents to new version in milliseconds.
*/
@NonNull
public SchemaMigrationStats.Builder setQueryAndTransformLatencyMillis(
int queryAndTransformLatencyMillis) {
mQueryAndTransformLatencyMillis = queryAndTransformLatencyMillis;
return this;
}
/** Sets latency of first SetSchema action in milliseconds. */
@NonNull
public SchemaMigrationStats.Builder setFirstSetSchemaLatencyMillis(
int firstSetSchemaLatencyMillis) {
mFirstSetSchemaLatencyMillis = firstSetSchemaLatencyMillis;
return this;
}
/** Sets latency of second SetSchema action in milliseconds. */
@NonNull
public SchemaMigrationStats.Builder setSecondSetSchemaLatencyMillis(
int secondSetSchemaLatencyMillis) {
mSecondSetSchemaLatencyMillis = secondSetSchemaLatencyMillis;
return this;
}
/** Sets latency for putting migrated document to Icing lib in milliseconds. */
@NonNull
public SchemaMigrationStats.Builder setSaveDocumentLatencyMillis(
int saveDocumentLatencyMillis) {
mSaveDocumentLatencyMillis = saveDocumentLatencyMillis;
return this;
}
/** Sets number of migrated documents. */
@NonNull
public SchemaMigrationStats.Builder setMigratedDocumentCount(int migratedDocumentCount) {
mMigratedDocumentCount = migratedDocumentCount;
return this;
}
/** Sets number of updated documents which are saved in Icing lib. */
@NonNull
public SchemaMigrationStats.Builder setSavedDocumentCount(int savedDocumentCount) {
mSavedDocumentCount = savedDocumentCount;
return this;
}
/**
* Builds a new {@link SchemaMigrationStats} from the {@link SchemaMigrationStats.Builder}.
*/
@NonNull
public SchemaMigrationStats build() {
return new SchemaMigrationStats(/* builder= */ this);
}
}
}

View File

@@ -17,6 +17,7 @@
package com.android.server.appsearch.external.localstorage.stats;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.appsearch.AppSearchResult;
import java.util.Objects;
@@ -38,6 +39,12 @@ public final class SetSchemaStats {
*/
@AppSearchResult.ResultCode private final int mStatusCode;
/**
* Stores stats of SchemaMigration in SetSchema process. Is {@code null} if no schema migration
* is needed.
*/
@Nullable private final SchemaMigrationStats mSchemaMigrationStats;
private final int mTotalLatencyMillis;
/** Overall time used for the native function call. */
@@ -63,6 +70,7 @@ public final class SetSchemaStats {
mPackageName = builder.mPackageName;
mDatabase = builder.mDatabase;
mStatusCode = builder.mStatusCode;
mSchemaMigrationStats = builder.mSchemaMigrationStats;
mTotalLatencyMillis = builder.mTotalLatencyMillis;
mNativeLatencyMillis = builder.mNativeLatencyMillis;
mNewTypeCount = builder.mNewTypeCount;
@@ -90,6 +98,15 @@ public final class SetSchemaStats {
return mStatusCode;
}
/**
* Returns the status of schema migration, if migration is executed during the SetSchema
* process. Otherwise, returns {@code null}.
*/
@Nullable
public SchemaMigrationStats getSchemaMigrationStats() {
return mSchemaMigrationStats;
}
/** Returns the total latency of the SetSchema action. */
public int getTotalLatencyMillis() {
return mTotalLatencyMillis;
@@ -140,6 +157,7 @@ public final class SetSchemaStats {
@NonNull final String mPackageName;
@NonNull final String mDatabase;
@AppSearchResult.ResultCode int mStatusCode;
@Nullable SchemaMigrationStats mSchemaMigrationStats;
int mTotalLatencyMillis;
int mNativeLatencyMillis;
int mNewTypeCount;
@@ -161,7 +179,14 @@ public final class SetSchemaStats {
return this;
}
/** Sets total latency for the SetSchema action. */
/** Sets the status of schema migration. */
@NonNull
public Builder setSchemaMigrationStats(@NonNull SchemaMigrationStats schemaMigrationStats) {
mSchemaMigrationStats = Objects.requireNonNull(schemaMigrationStats);
return this;
}
/** Sets total latency for the SetSchema action in milliseconds. */
@NonNull
public Builder setTotalLatencyMillis(int totalLatencyMillis) {
mTotalLatencyMillis = totalLatencyMillis;

View File

@@ -27,7 +27,7 @@ import java.util.Set;
*
* This object is not thread safe.
*/
class NotPlatformSurfaceableMap {
class NotDisplayedBySystemMap {
/**
* Maps packages to databases to the set of prefixed schemas that are platform-hidden within
* that database.
@@ -39,7 +39,7 @@ class NotPlatformSurfaceableMap {
*
* <p>Any existing mappings for this prefix are overwritten.
*/
public void setNotPlatformSurfaceable(
public void setNotDisplayedBySystem(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull Set<String> prefixedSchemas) {
@@ -55,7 +55,7 @@ class NotPlatformSurfaceableMap {
* Returns whether the given prefixed schema is platform surfaceable (has not opted out) in the
* given database.
*/
public boolean isSchemaPlatformSurfaceable(
public boolean isSchemaDisplayedBySystem(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String prefixedSchema) {

View File

@@ -28,10 +28,10 @@ class VisibilityDocument extends GenericDocument {
/**
* Property that holds the list of platform-hidden schemas, as part of the visibility settings.
*/
private static final String NOT_PLATFORM_SURFACEABLE_PROPERTY = "notPlatformSurfaceable";
private static final String NOT_DISPLAYED_BY_SYSTEM_PROPERTY = "notPlatformSurfaceable";
/** Property that holds nested documents of package accessible schemas. */
private static final String PACKAGE_ACCESSIBLE_PROPERTY = "packageAccessible";
private static final String VISIBLE_TO_PACKAGES_PROPERTY = "packageAccessible";
/**
* Schema for the VisibilityStore's documents.
@@ -41,11 +41,11 @@ class VisibilityDocument extends GenericDocument {
*/
public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
NOT_PLATFORM_SURFACEABLE_PROPERTY)
NOT_DISPLAYED_BY_SYSTEM_PROPERTY)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
.addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
PACKAGE_ACCESSIBLE_PROPERTY, PackageAccessibleDocument.SCHEMA_TYPE)
VISIBLE_TO_PACKAGES_PROPERTY, VisibleToPackagesDocument.SCHEMA_TYPE)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build())
.build();
@@ -55,13 +55,13 @@ class VisibilityDocument extends GenericDocument {
}
@Nullable
public String[] getNotPlatformSurfaceableSchemas() {
return getPropertyStringArray(NOT_PLATFORM_SURFACEABLE_PROPERTY);
public String[] getNotDisplayedBySystem() {
return getPropertyStringArray(NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
}
@Nullable
public GenericDocument[] getPackageAccessibleSchemas() {
return getPropertyDocumentArray(PACKAGE_ACCESSIBLE_PROPERTY);
public GenericDocument[] getVisibleToPackages() {
return getPropertyDocumentArray(VISIBLE_TO_PACKAGES_PROPERTY);
}
/** Builder for {@link VisibilityDocument}. */
@@ -72,17 +72,15 @@ class VisibilityDocument extends GenericDocument {
/** Sets which prefixed schemas have opted out of platform surfacing. */
@NonNull
public Builder setSchemasNotPlatformSurfaceable(
@NonNull String[] notPlatformSurfaceableSchemas) {
return setPropertyString(
NOT_PLATFORM_SURFACEABLE_PROPERTY, notPlatformSurfaceableSchemas);
public Builder setNotDisplayedBySystem(@NonNull String[] notDisplayedBySystemSchemas) {
return setPropertyString(NOT_DISPLAYED_BY_SYSTEM_PROPERTY, notDisplayedBySystemSchemas);
}
/** Sets which prefixed schemas have configured package access. */
@NonNull
public Builder setPackageAccessibleSchemas(
@NonNull PackageAccessibleDocument[] packageAccessibleSchemas) {
return setPropertyDocument(PACKAGE_ACCESSIBLE_PROPERTY, packageAccessibleSchemas);
public Builder setVisibleToPackages(
@NonNull VisibleToPackagesDocument[] visibleToPackagesDocuments) {
return setPropertyDocument(VISIBLE_TO_PACKAGES_PROPERTY, visibleToPackagesDocuments);
}
}
}

View File

@@ -66,9 +66,6 @@ import java.util.Set;
* @hide
*/
public class VisibilityStore {
/** No-op uid that won't have any visibility settings. */
public static final int NO_OP_UID = -1;
/** Version for the visibility schema */
private static final int SCHEMA_VERSION = 0;
@@ -92,11 +89,10 @@ public class VisibilityStore {
private final Context mUserContext;
/** Stores the schemas that are platform-hidden. All values are prefixed. */
private final NotPlatformSurfaceableMap mNotPlatformSurfaceableMap =
new NotPlatformSurfaceableMap();
private final NotDisplayedBySystemMap mNotDisplayedBySystemMap = new NotDisplayedBySystemMap();
/** Stores the schemas that are package accessible. All values are prefixed. */
private final PackageAccessibleMap mPackageAccessibleMap = new PackageAccessibleMap();
/** Stores the schemas that are visible to 3p packages. All values are prefixed. */
private final VisibleToPackagesMap mVisibleToPackagesMap = new VisibleToPackagesMap();
/**
* Creates and initializes VisibilityStore.
@@ -118,28 +114,28 @@ public class VisibilityStore {
GetSchemaResponse getSchemaResponse = mAppSearchImpl.getSchema(PACKAGE_NAME, DATABASE_NAME);
boolean hasVisibilityType = false;
boolean hasPackageAccessibleType = false;
boolean hasVisibleToPackagesType = false;
for (AppSearchSchema schema : getSchemaResponse.getSchemas()) {
if (schema.getSchemaType().equals(VisibilityDocument.SCHEMA_TYPE)) {
hasVisibilityType = true;
} else if (schema.getSchemaType().equals(PackageAccessibleDocument.SCHEMA_TYPE)) {
hasPackageAccessibleType = true;
} else if (schema.getSchemaType().equals(VisibleToPackagesDocument.SCHEMA_TYPE)) {
hasVisibleToPackagesType = true;
}
if (hasVisibilityType && hasPackageAccessibleType) {
if (hasVisibilityType && hasVisibleToPackagesType) {
// Found both our types, can exit early.
break;
}
}
if (!hasVisibilityType || !hasPackageAccessibleType) {
if (!hasVisibilityType || !hasVisibleToPackagesType) {
// Schema type doesn't exist yet. Add it.
mAppSearchImpl.setSchema(
PACKAGE_NAME,
DATABASE_NAME,
Arrays.asList(VisibilityDocument.SCHEMA, PackageAccessibleDocument.SCHEMA),
Arrays.asList(VisibilityDocument.SCHEMA, VisibleToPackagesDocument.SCHEMA),
/*visibilityStore=*/ null, // Avoid recursive calls
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ SCHEMA_VERSION);
}
@@ -177,26 +173,25 @@ public class VisibilityStore {
}
// Update platform visibility settings
String[] notPlatformSurfaceableSchemas =
visibilityDocument.getNotPlatformSurfaceableSchemas();
if (notPlatformSurfaceableSchemas != null) {
mNotPlatformSurfaceableMap.setNotPlatformSurfaceable(
String[] notDisplayedBySystemSchemas = visibilityDocument.getNotDisplayedBySystem();
if (notDisplayedBySystemSchemas != null) {
mNotDisplayedBySystemMap.setNotDisplayedBySystem(
packageName,
databaseName,
new ArraySet<>(notPlatformSurfaceableSchemas));
new ArraySet<>(notDisplayedBySystemSchemas));
}
// Update 3p package visibility settings
Map<String, Set<PackageIdentifier>> schemaToPackageIdentifierMap = new ArrayMap<>();
GenericDocument[] packageAccessibleDocuments =
visibilityDocument.getPackageAccessibleSchemas();
if (packageAccessibleDocuments != null) {
for (int i = 0; i < packageAccessibleDocuments.length; i++) {
PackageAccessibleDocument packageAccessibleDocument =
new PackageAccessibleDocument(packageAccessibleDocuments[i]);
GenericDocument[] visibleToPackagesDocuments =
visibilityDocument.getVisibleToPackages();
if (visibleToPackagesDocuments != null) {
for (int i = 0; i < visibleToPackagesDocuments.length; i++) {
VisibleToPackagesDocument visibleToPackagesDocument =
new VisibleToPackagesDocument(visibleToPackagesDocuments[i]);
PackageIdentifier packageIdentifier =
packageAccessibleDocument.getPackageIdentifier();
String prefixedSchema = packageAccessibleDocument.getAccessibleSchemaType();
visibleToPackagesDocument.getPackageIdentifier();
String prefixedSchema = visibleToPackagesDocument.getAccessibleSchemaType();
Set<PackageIdentifier> packageIdentifiers =
schemaToPackageIdentifierMap.get(prefixedSchema);
if (packageIdentifiers == null) {
@@ -206,7 +201,7 @@ public class VisibilityStore {
schemaToPackageIdentifierMap.put(prefixedSchema, packageIdentifiers);
}
}
mPackageAccessibleMap.setPackageAccessible(
mVisibleToPackagesMap.setVisibleToPackages(
packageName, databaseName, schemaToPackageIdentifierMap);
}
}
@@ -216,51 +211,51 @@ public class VisibilityStore {
* Sets visibility settings for the given database. Any previous visibility settings will be
* overwritten.
*
* @param packageName Package of app that owns the {@code schemasNotPlatformSurfaceable}.
* @param databaseName Database that owns the {@code schemasNotPlatformSurfaceable}.
* @param schemasNotPlatformSurfaceable Set of prefixed schemas that should be hidden from the
* @param packageName Package of app that owns the schemas.
* @param databaseName Database that owns the schemas.
* @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from the
* platform.
* @param schemasPackageAccessible Map of prefixed schemas to a list of package identifiers that
* @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
* have access to the schema.
* @throws AppSearchException on AppSearchImpl error.
*/
public void setVisibility(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull Set<String> schemasNotPlatformSurfaceable,
@NonNull Map<String, List<PackageIdentifier>> schemasPackageAccessible)
@NonNull Set<String> schemasNotDisplayedBySystem,
@NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
throws AppSearchException {
Objects.requireNonNull(packageName);
Objects.requireNonNull(databaseName);
Objects.requireNonNull(schemasNotPlatformSurfaceable);
Objects.requireNonNull(schemasPackageAccessible);
Objects.requireNonNull(schemasNotDisplayedBySystem);
Objects.requireNonNull(schemasVisibleToPackages);
// Persist the document
VisibilityDocument.Builder visibilityDocument =
new VisibilityDocument.Builder(
NAMESPACE, /*id=*/ getVisibilityDocumentId(packageName, databaseName));
if (!schemasNotPlatformSurfaceable.isEmpty()) {
visibilityDocument.setSchemasNotPlatformSurfaceable(
schemasNotPlatformSurfaceable.toArray(new String[0]));
if (!schemasNotDisplayedBySystem.isEmpty()) {
visibilityDocument.setNotDisplayedBySystem(
schemasNotDisplayedBySystem.toArray(new String[0]));
}
Map<String, Set<PackageIdentifier>> schemaToPackageIdentifierMap = new ArrayMap<>();
List<PackageAccessibleDocument> packageAccessibleDocuments = new ArrayList<>();
List<VisibleToPackagesDocument> visibleToPackagesDocuments = new ArrayList<>();
for (Map.Entry<String, List<PackageIdentifier>> entry :
schemasPackageAccessible.entrySet()) {
schemasVisibleToPackages.entrySet()) {
for (int i = 0; i < entry.getValue().size(); i++) {
PackageAccessibleDocument packageAccessibleDocument =
new PackageAccessibleDocument.Builder(NAMESPACE, /*id=*/ "")
VisibleToPackagesDocument visibleToPackagesDocument =
new VisibleToPackagesDocument.Builder(NAMESPACE, /*id=*/ "")
.setAccessibleSchemaType(entry.getKey())
.setPackageIdentifier(entry.getValue().get(i))
.build();
packageAccessibleDocuments.add(packageAccessibleDocument);
visibleToPackagesDocuments.add(visibleToPackagesDocument);
}
schemaToPackageIdentifierMap.put(entry.getKey(), new ArraySet<>(entry.getValue()));
}
if (!packageAccessibleDocuments.isEmpty()) {
visibilityDocument.setPackageAccessibleSchemas(
packageAccessibleDocuments.toArray(new PackageAccessibleDocument[0]));
if (!visibleToPackagesDocuments.isEmpty()) {
visibilityDocument.setVisibleToPackages(
visibleToPackagesDocuments.toArray(new VisibleToPackagesDocument[0]));
}
mAppSearchImpl.putDocument(
@@ -269,9 +264,9 @@ public class VisibilityStore {
mAppSearchImpl.persistToDisk(PersistType.Code.LITE);
// Update derived data structures.
mNotPlatformSurfaceableMap.setNotPlatformSurfaceable(
packageName, databaseName, schemasNotPlatformSurfaceable);
mPackageAccessibleMap.setPackageAccessible(
mNotDisplayedBySystemMap.setNotDisplayedBySystem(
packageName, databaseName, schemasNotDisplayedBySystem);
mVisibleToPackagesMap.setVisibleToPackages(
packageName, databaseName, schemaToPackageIdentifierMap);
}
@@ -313,13 +308,13 @@ public class VisibilityStore {
}
if (callerHasSystemAccess
&& mNotPlatformSurfaceableMap.isSchemaPlatformSurfaceable(
&& mNotDisplayedBySystemMap.isSchemaDisplayedBySystem(
packageName, databaseName, prefixedSchema)) {
return true;
}
// May not be platform surfaceable, but might still be accessible through 3p access.
return isSchemaPackageAccessible(packageName, databaseName, prefixedSchema, callerUid);
return isSchemaVisibleToPackages(packageName, databaseName, prefixedSchema, callerUid);
}
/**
@@ -331,13 +326,13 @@ public class VisibilityStore {
* certificate was once used to sign the package, the package will still be granted access. This
* does not handle packages that have been signed by multiple certificates.
*/
private boolean isSchemaPackageAccessible(
private boolean isSchemaVisibleToPackages(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull String prefixedSchema,
int callerUid) {
Set<PackageIdentifier> packageIdentifiers =
mPackageAccessibleMap.getAccessiblePackages(
mVisibleToPackagesMap.getAccessiblePackages(
packageName, databaseName, prefixedSchema);
if (packageIdentifiers.isEmpty()) {
return false;

View File

@@ -26,7 +26,7 @@ import android.app.appsearch.PackageIdentifier;
*
* @see android.app.appsearch.SetSchemaRequest.Builder#setSchemaTypeVisibilityForPackage
*/
class PackageAccessibleDocument extends GenericDocument {
class VisibleToPackagesDocument extends GenericDocument {
/** Schema type for nested documents that hold package accessible information. */
public static final String SCHEMA_TYPE = "PackageAccessibleType";
@@ -59,7 +59,7 @@ class PackageAccessibleDocument extends GenericDocument {
.build())
.build();
public PackageAccessibleDocument(@NonNull GenericDocument genericDocument) {
VisibleToPackagesDocument(@NonNull GenericDocument genericDocument) {
super(genericDocument);
}
@@ -76,9 +76,9 @@ class PackageAccessibleDocument extends GenericDocument {
return new PackageIdentifier(packageName, sha256Cert);
}
/** Builder for {@link PackageAccessibleDocument} instances. */
public static class Builder extends GenericDocument.Builder<PackageAccessibleDocument.Builder> {
public Builder(@NonNull String namespace, @NonNull String id) {
/** Builder for {@link VisibleToPackagesDocument} instances. */
public static class Builder extends GenericDocument.Builder<VisibleToPackagesDocument.Builder> {
Builder(@NonNull String namespace, @NonNull String id) {
super(namespace, id, SCHEMA_TYPE);
}
@@ -98,8 +98,8 @@ class PackageAccessibleDocument extends GenericDocument {
@Override
@NonNull
public PackageAccessibleDocument build() {
return new PackageAccessibleDocument(super.build());
public VisibleToPackagesDocument build() {
return new VisibleToPackagesDocument(super.build());
}
}
}

View File

@@ -29,7 +29,7 @@ import java.util.Set;
*
* This object is not thread safe.
*/
class PackageAccessibleMap {
class VisibleToPackagesMap {
/**
* Maps packages to databases to prefixed schemas to PackageIdentifiers that have access to that
* schema.
@@ -42,7 +42,7 @@ class PackageAccessibleMap {
*
* <p>Any existing mappings for this prefix are overwritten.
*/
public void setPackageAccessible(
public void setVisibleToPackages(
@NonNull String packageName,
@NonNull String databaseName,
@NonNull Map<String, Set<PackageIdentifier>> schemaToPackageIdentifier) {

View File

@@ -1 +1 @@
31a54dba5bda4d0109ea91eb1ac047c937cbaae3
04351b43fbbf9d59ffeae41903322023931c84f2

View File

@@ -51,8 +51,6 @@ public interface AppSearchSessionShim extends Closeable {
* @param request the schema to set or update the AppSearch database to.
* @return a {@link ListenableFuture} which resolves to a {@link SetSchemaResponse} object.
*/
// TODO(b/169883602): Change @code references to @link when setPlatformSurfaceable APIs are
// exposed.
@NonNull
ListenableFuture<SetSchemaResponse> setSchema(@NonNull SetSchemaRequest request);

View File

@@ -18,7 +18,7 @@ package android.app.appsearch;
import static com.google.common.truth.Truth.assertThat;
import static org.testng.Assert.expectThrows;
import static org.junit.Assert.assertThrows;
import org.junit.Test;
@@ -26,7 +26,7 @@ public class AppSearchResultTest {
@Test
public void testMapNullPointerException() {
NullPointerException e =
expectThrows(
assertThrows(
NullPointerException.class,
() -> {
Object o = null;

View File

@@ -127,8 +127,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema1",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
@@ -159,8 +159,8 @@ public class AppSearchImplPlatformTest {
new AppSearchSchema.Builder("schema1").build(),
new AppSearchSchema.Builder("schema2").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema1",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
@@ -233,8 +233,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("schema1"),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.singletonList("schema1"),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema1",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,
@@ -263,8 +263,8 @@ public class AppSearchImplPlatformTest {
"database",
/*schemas=*/ Collections.emptyList(),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*schemaVersion=*/ 0);
@@ -292,8 +292,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("schema1").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
@@ -327,8 +327,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
@@ -355,8 +355,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.singletonList("Schema"),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.singletonList("Schema"),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
@@ -370,7 +370,7 @@ public class AppSearchImplPlatformTest {
}
@Test
public void testSetSchema_defaultNotPackageAccessible() throws Exception {
public void testSetSchema_defaultNotVisibleToPackages() throws Exception {
String packageName = "com.package";
// Make sure package doesn't global query privileges
@@ -384,8 +384,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*schemaVersion=*/ 0);
assertThat(mVisibilityStore
@@ -399,7 +399,7 @@ public class AppSearchImplPlatformTest {
}
@Test
public void testSetSchema_packageAccessible() throws Exception {
public void testSetSchema_visibleToPackages() throws Exception {
// Values for a "foo" client
String packageNameFoo = "packageFoo";
byte[] sha256CertFoo = new byte[] {10};
@@ -423,8 +423,8 @@ public class AppSearchImplPlatformTest {
"database",
Collections.singletonList(new AppSearchSchema.Builder("Schema").build()),
mVisibilityStore,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"Schema",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))),
/*forceOverride=*/ false,

View File

@@ -132,7 +132,7 @@ public class VisibilityStoreTest {
}
@Test
public void testSetVisibility_platformSurfaceable() throws Exception {
public void testSetVisibility_displayedBySystem() throws Exception {
// Make sure we have global query privileges
PackageManager mockPackageManager = getMockPackageManager(mContext.getUser());
when(mockPackageManager
@@ -143,9 +143,9 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
/*schemasNotPlatformSurfaceable=*/ ImmutableSet.of(
/*schemasNotDisplayedBySystem=*/ ImmutableSet.of(
"prefix/schema1", "prefix/schema2"),
/*schemasPackageAccessible=*/ Collections.emptyMap());
/*schemasVisibleToPackages=*/ Collections.emptyMap());
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
@@ -168,9 +168,9 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
/*schemasNotPlatformSurfaceable=*/ ImmutableSet.of(
/*schemasNotDisplayedBySystem=*/ ImmutableSet.of(
"prefix/schema1", "prefix/schema3"),
/*schemasPackageAccessible=*/ Collections.emptyMap());
/*schemasVisibleToPackages=*/ Collections.emptyMap());
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
@@ -200,8 +200,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
/*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
/*schemasPackageAccessible=*/ Collections.emptyMap());
/*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
/*schemasVisibleToPackages=*/ Collections.emptyMap());
assertThat(
mVisibilityStore.isSchemaSearchableByCaller(
"package",
@@ -229,7 +229,7 @@ public class VisibilityStoreTest {
}
@Test
public void testSetVisibility_packageAccessible() throws Exception {
public void testSetVisibility_visibleToPackages() throws Exception {
// Values for a "foo" client
String packageNameFoo = "packageFoo";
byte[] sha256CertFoo = new byte[] {10};
@@ -272,8 +272,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
/*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"prefix/schemaFoo",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo)),
"prefix/schemaBar",
@@ -339,8 +339,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
/*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"prefix/schemaFoo",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
@@ -392,8 +392,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
"package",
"database",
/*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"prefix/schemaFoo",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));
@@ -425,8 +425,8 @@ public class VisibilityStoreTest {
mVisibilityStore.setVisibility(
/*packageName=*/ "",
/*databaseName=*/ "",
/*schemasNotPlatformSurfaceable=*/ Collections.emptySet(),
/*schemasPackageAccessible=*/ ImmutableMap.of(
/*schemasNotDisplayedBySystem=*/ Collections.emptySet(),
/*schemasVisibleToPackages=*/ ImmutableMap.of(
"schema",
ImmutableList.of(new PackageIdentifier(packageNameFoo, sha256CertFoo))));

View File

@@ -22,7 +22,7 @@ import static com.android.server.appsearch.external.localstorage.util.PrefixUtil
import static com.google.common.truth.Truth.assertThat;
import static org.testng.Assert.expectThrows;
import static org.junit.Assert.assertThrows;
import android.app.appsearch.AppSearchResult;
import android.app.appsearch.AppSearchSchema;
@@ -34,6 +34,7 @@ import android.app.appsearch.SetSchemaResponse;
import android.app.appsearch.StorageInfo;
import android.app.appsearch.exceptions.AppSearchException;
import android.content.Context;
import android.os.Process;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -55,7 +56,6 @@ import com.android.server.appsearch.proto.SearchSpecProto;
import com.android.server.appsearch.proto.StatusProto;
import com.android.server.appsearch.proto.StringIndexingConfig;
import com.android.server.appsearch.proto.TermMatchType;
import com.android.server.appsearch.visibilitystore.VisibilityStore;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -391,7 +391,7 @@ public class AppSearchImplTest {
DocumentProto.Builder actualDocument = documentProto.toBuilder();
AppSearchException e =
expectThrows(
assertThrows(
AppSearchException.class, () -> removePrefixesFromDocument(actualDocument));
assertThat(e).hasMessageThat().contains("Found unexpected multiple prefix names");
}
@@ -416,7 +416,7 @@ public class AppSearchImplTest {
DocumentProto.Builder actualDocument = documentProto.toBuilder();
AppSearchException e =
expectThrows(
assertThrows(
AppSearchException.class, () -> removePrefixesFromDocument(actualDocument));
assertThat(e).hasMessageThat().contains("Found unexpected multiple prefix names");
}
@@ -431,8 +431,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -480,8 +480,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -499,7 +499,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
/*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
@@ -513,7 +513,7 @@ public class AppSearchImplTest {
.setSchema(context.getPackageName() + "$database1/Type1")
.build();
AppSearchException e =
expectThrows(
assertThrows(
AppSearchException.class,
() -> PrefixUtil.getPrefix(invalidDoc.getNamespace()));
assertThat(e)
@@ -538,10 +538,8 @@ public class AppSearchImplTest {
assertThat(initStats.hasDeSync()).isFalse();
assertThat(initStats.getDocumentStoreRecoveryCause())
.isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
// TODO(b/187879464): There should not be a recovery here, but icing lib reports one if the
// doc had no tokens. Once the mentioned bug is fixed, uncomment this.
// assertThat(initStats.getIndexRestorationCause())
// .isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
assertThat(initStats.getIndexRestorationCause())
.isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
assertThat(initStats.getSchemaStoreRecoveryCause())
.isEqualTo(InitializeStats.RECOVERY_CAUSE_NONE);
assertThat(initStats.getDocumentStoreDataStatus())
@@ -558,7 +556,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
/*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).isEmpty();
@@ -569,8 +567,8 @@ public class AppSearchImplTest {
"database1",
Collections.singletonList(new AppSearchSchema.Builder("Type1").build()),
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -585,7 +583,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().addFilterSchemas("Type1").build(),
context.getPackageName(),
/*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(results.getResults()).hasSize(1);
@@ -604,8 +602,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -638,8 +636,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -647,8 +645,8 @@ public class AppSearchImplTest {
"database2",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -692,8 +690,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -734,8 +732,8 @@ public class AppSearchImplTest {
"database1",
schema1,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -747,8 +745,8 @@ public class AppSearchImplTest {
"database2",
schema2,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -790,8 +788,8 @@ public class AppSearchImplTest {
"database1",
schema1,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -803,8 +801,8 @@ public class AppSearchImplTest {
"database2",
schema2,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -851,7 +849,7 @@ public class AppSearchImplTest {
searchSpec,
/*callerPackageName=*/ "",
/*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null);
assertThat(searchResultPage.getResults()).isEmpty();
@@ -893,8 +891,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -938,8 +936,8 @@ public class AppSearchImplTest {
"database1",
oldSchemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -954,8 +952,8 @@ public class AppSearchImplTest {
"database1",
newSchemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*version=*/ 0);
assertThat(setSchemaResponse.getDeletedTypes()).containsExactly("Text");
@@ -977,8 +975,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1010,8 +1008,8 @@ public class AppSearchImplTest {
"database1",
finalSchemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1024,8 +1022,8 @@ public class AppSearchImplTest {
"database1",
finalSchemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*version=*/ 0);
@@ -1062,8 +1060,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -1071,8 +1069,8 @@ public class AppSearchImplTest {
"database2",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1111,8 +1109,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ true,
/*version=*/ 0);
@@ -1156,8 +1154,8 @@ public class AppSearchImplTest {
"database",
schema,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1218,8 +1216,8 @@ public class AppSearchImplTest {
"database",
schema,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -1227,8 +1225,8 @@ public class AppSearchImplTest {
"database",
schema,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1273,8 +1271,8 @@ public class AppSearchImplTest {
"database1",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
assertThat(mAppSearchImpl.getPackageToDatabases())
@@ -1287,8 +1285,8 @@ public class AppSearchImplTest {
"database2",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
assertThat(mAppSearchImpl.getPackageToDatabases())
@@ -1301,8 +1299,8 @@ public class AppSearchImplTest {
"database1",
Collections.singletonList(new AppSearchSchema.Builder("schema").build()),
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
assertThat(mAppSearchImpl.getPackageToDatabases())
@@ -1360,8 +1358,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1511,8 +1509,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1534,8 +1532,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1550,8 +1548,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1599,8 +1597,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1622,8 +1620,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1644,8 +1642,8 @@ public class AppSearchImplTest {
"database1",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
mAppSearchImpl.setSchema(
@@ -1653,8 +1651,8 @@ public class AppSearchImplTest {
"database2",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1700,15 +1698,15 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
appSearchImpl.close();
// Check all our public APIs
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.setSchema(
@@ -1716,15 +1714,15 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0));
expectThrows(
assertThrows(
IllegalStateException.class, () -> appSearchImpl.getSchema("package", "database"));
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.putDocument(
@@ -1733,13 +1731,13 @@ public class AppSearchImplTest {
new GenericDocument.Builder<>("namespace", "id", "type").build(),
/*logger=*/ null));
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.getDocument(
"package", "database", "namespace", "id", Collections.emptyMap()));
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.query(
@@ -1749,7 +1747,7 @@ public class AppSearchImplTest {
new SearchSpec.Builder().build(),
/*logger=*/ null));
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.globalQuery(
@@ -1757,19 +1755,19 @@ public class AppSearchImplTest {
new SearchSpec.Builder().build(),
"package",
/*visibilityStore=*/ null,
VisibilityStore.NO_OP_UID,
Process.INVALID_UID,
/*callerHasSystemAccess=*/ false,
/*logger=*/ null));
expectThrows(
assertThrows(
IllegalStateException.class,
() -> appSearchImpl.getNextPage(/*nextPageToken=*/ 1L));
expectThrows(
assertThrows(
IllegalStateException.class,
() -> appSearchImpl.invalidateNextPageToken(/*nextPageToken=*/ 1L));
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.reportUsage(
@@ -1780,7 +1778,7 @@ public class AppSearchImplTest {
/*usageTimestampMillis=*/ 1000L,
/*systemUsage=*/ false));
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.remove(
@@ -1790,7 +1788,7 @@ public class AppSearchImplTest {
"id",
/*removeStatsBuilder=*/ null));
expectThrows(
assertThrows(
IllegalStateException.class,
() ->
appSearchImpl.removeByQuery(
@@ -1800,15 +1798,15 @@ public class AppSearchImplTest {
new SearchSpec.Builder().build(),
/*removeStatsBuilder=*/ null));
expectThrows(
assertThrows(
IllegalStateException.class,
() -> appSearchImpl.getStorageInfoForPackage("package"));
expectThrows(
assertThrows(
IllegalStateException.class,
() -> appSearchImpl.getStorageInfoForDatabase("package", "database"));
expectThrows(
assertThrows(
IllegalStateException.class,
() -> appSearchImpl.persistToDisk(PersistType.Code.FULL));
}
@@ -1827,8 +1825,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1866,8 +1864,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1892,7 +1890,7 @@ public class AppSearchImplTest {
// Delete the first document
appSearchImpl.remove("package", "database", "namespace1", "id1", /*statsBuilder=*/ null);
appSearchImpl.persistToDisk(PersistType.Code.LITE);
expectThrows(
assertThrows(
AppSearchException.class,
() ->
appSearchImpl.getDocument(
@@ -1909,7 +1907,7 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
expectThrows(
assertThrows(
AppSearchException.class,
() ->
appSearchImpl2.getDocument(
@@ -1938,8 +1936,8 @@ public class AppSearchImplTest {
"database",
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
@@ -1972,7 +1970,7 @@ public class AppSearchImplTest {
.build(),
/*statsBuilder=*/ null);
appSearchImpl.persistToDisk(PersistType.Code.LITE);
expectThrows(
assertThrows(
AppSearchException.class,
() ->
appSearchImpl.getDocument(
@@ -1989,7 +1987,7 @@ public class AppSearchImplTest {
// Only the second document should be retrievable from another instance.
AppSearchImpl appSearchImpl2 =
AppSearchImpl.create(appsearchDir, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
expectThrows(
assertThrows(
AppSearchException.class,
() ->
appSearchImpl2.getDocument(

View File

@@ -25,6 +25,7 @@ import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
import android.app.appsearch.SearchResultPage;
import android.app.appsearch.SearchSpec;
import android.app.appsearch.exceptions.AppSearchException;
import com.android.server.appsearch.external.localstorage.stats.CallStats;
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
@@ -32,17 +33,24 @@ import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
import com.android.server.appsearch.proto.DeleteStatsProto;
import com.android.server.appsearch.proto.DocumentProto;
import com.android.server.appsearch.proto.InitializeStatsProto;
import com.android.server.appsearch.proto.PutDocumentStatsProto;
import com.android.server.appsearch.proto.PutResultProto;
import com.android.server.appsearch.proto.QueryStatsProto;
import com.android.server.appsearch.proto.ScoringSpecProto;
import com.android.server.appsearch.proto.StatusProto;
import com.android.server.appsearch.proto.TermMatchType;
import com.google.common.collect.ImmutableList;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.util.Collections;
import java.util.List;
@@ -279,7 +287,7 @@ public class AppSearchLoggerTest {
// Testing actual logging
//
@Test
public void testLoggingStats_initialize() throws Exception {
public void testLoggingStats_initializeWithoutDocuments_success() throws Exception {
// Create an unused AppSearchImpl to generated an InitializeStats.
InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
AppSearchImpl.create(mTemporaryFolder.newFolder(), initStatsBuilder, ALWAYS_OPTIMIZE);
@@ -295,25 +303,139 @@ public class AppSearchLoggerTest {
.isEqualTo(InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
assertThat(iStats.getDocumentCount()).isEqualTo(0);
assertThat(iStats.getSchemaTypeCount()).isEqualTo(0);
assertThat(iStats.hasReset()).isEqualTo(false);
assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
}
@Test
public void testLoggingStats_putDocument() throws Exception {
public void testLoggingStats_initializeWithDocuments_success() throws Exception {
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
final File folder = mTemporaryFolder.newFolder();
AppSearchImpl appSearchImpl =
AppSearchImpl.create(folder, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
ImmutableList.of(
new AppSearchSchema.Builder("Type1").build(),
new AppSearchSchema.Builder("Type2").build());
appSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
GenericDocument doc2 = new GenericDocument.Builder<>("namespace", "id2", "Type1").build();
appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
appSearchImpl.putDocument(testPackageName, testDatabase, doc2, mLogger);
appSearchImpl.close();
// Create another appsearchImpl on the same folder
InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
AppSearchImpl.create(folder, initStatsBuilder, ALWAYS_OPTIMIZE);
InitializeStats iStats = initStatsBuilder.build();
assertThat(iStats).isNotNull();
assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
// Total latency captured in LocalStorage
assertThat(iStats.getTotalLatencyMillis()).isEqualTo(0);
assertThat(iStats.hasDeSync()).isFalse();
assertThat(iStats.getNativeLatencyMillis()).isGreaterThan(0);
assertThat(iStats.getDocumentStoreDataStatus())
.isEqualTo(InitializeStatsProto.DocumentStoreDataStatus.NO_DATA_LOSS_VALUE);
assertThat(iStats.getDocumentCount()).isEqualTo(2);
assertThat(iStats.getSchemaTypeCount()).isEqualTo(2);
assertThat(iStats.hasReset()).isEqualTo(false);
assertThat(iStats.getResetStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
}
@Test
public void testLoggingStats_initialize_failure() throws Exception {
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
final File folder = mTemporaryFolder.newFolder();
AppSearchImpl appSearchImpl =
AppSearchImpl.create(folder, /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
List<AppSearchSchema> schemas =
ImmutableList.of(
new AppSearchSchema.Builder("Type1").build(),
new AppSearchSchema.Builder("Type2").build());
appSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
// Insert a valid doc
GenericDocument doc1 = new GenericDocument.Builder<>("namespace", "id1", "Type1").build();
appSearchImpl.putDocument(testPackageName, testDatabase, doc1, mLogger);
// Insert the invalid doc with an invalid namespace right into icing
DocumentProto invalidDoc =
DocumentProto.newBuilder()
.setNamespace("invalidNamespace")
.setUri("id2")
.setSchema(String.format("%s$%s/Type1", testPackageName, testDatabase))
.build();
PutResultProto putResultProto = appSearchImpl.mIcingSearchEngineLocked.put(invalidDoc);
assertThat(putResultProto.getStatus().getCode()).isEqualTo(StatusProto.Code.OK);
appSearchImpl.close();
// Create another appsearchImpl on the same folder
InitializeStats.Builder initStatsBuilder = new InitializeStats.Builder();
AppSearchImpl.create(folder, initStatsBuilder, ALWAYS_OPTIMIZE);
InitializeStats iStats = initStatsBuilder.build();
// Some of other fields are already covered by AppSearchImplTest#testReset()
assertThat(iStats).isNotNull();
assertThat(iStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_INTERNAL_ERROR);
assertThat(iStats.hasReset()).isTrue();
}
@Test
public void testLoggingStats_putDocument_success() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
AppSearchSchema testSchema =
new AppSearchSchema.Builder("type")
.addProperty(
new AppSearchSchema.StringPropertyConfig.Builder("subject")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
AppSearchSchema.StringPropertyConfig
.INDEXING_TYPE_PREFIXES)
.setTokenizerType(
AppSearchSchema.StringPropertyConfig
.TOKENIZER_TYPE_PLAIN)
.build())
.build();
List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
mAppSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
GenericDocument document =
new GenericDocument.Builder<>("namespace", "id", "type")
.setPropertyString("subject", "testPut example1")
.build();
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
@@ -322,43 +444,119 @@ public class AppSearchLoggerTest {
assertThat(pStats.getPackageName()).isEqualTo(testPackageName);
assertThat(pStats.getDatabase()).isEqualTo(testDatabase);
assertThat(pStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
// The rest of native stats have been tested in testCopyNativeStats
// The latency related native stats have been tested in testCopyNativeStats
assertThat(pStats.getNativeDocumentSizeBytes()).isGreaterThan(0);
assertThat(pStats.getNativeNumTokensIndexed()).isGreaterThan(0);
}
@Test
public void testLoggingStats_search() throws Exception {
public void testLoggingStats_putDocument_failure() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
AppSearchSchema testSchema =
new AppSearchSchema.Builder("type")
.addProperty(
new AppSearchSchema.StringPropertyConfig.Builder("subject")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
AppSearchSchema.StringPropertyConfig
.INDEXING_TYPE_PREFIXES)
.setTokenizerType(
AppSearchSchema.StringPropertyConfig
.TOKENIZER_TYPE_PLAIN)
.build())
.build();
List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
mAppSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document = new GenericDocument.Builder<>("namespace", "id", "type").build();
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger);
GenericDocument document =
new GenericDocument.Builder<>("namespace", "id", "type")
.setPropertyString("nonExist", "testPut example1")
.build();
// We mainly want to check the status code in stats. So we don't need to inspect the
// exception here.
Assert.assertThrows(
AppSearchException.class,
() -> mAppSearchImpl.putDocument(testPackageName, testDatabase, document, mLogger));
PutDocumentStats pStats = mLogger.mPutDocumentStats;
assertThat(pStats).isNotNull();
assertThat(pStats.getPackageName()).isEqualTo(testPackageName);
assertThat(pStats.getDatabase()).isEqualTo(testDatabase);
assertThat(pStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
}
@Test
public void testLoggingStats_search_success() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
AppSearchSchema testSchema =
new AppSearchSchema.Builder("type")
.addProperty(
new AppSearchSchema.StringPropertyConfig.Builder("subject")
.setCardinality(
AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setIndexingType(
AppSearchSchema.StringPropertyConfig
.INDEXING_TYPE_PREFIXES)
.setTokenizerType(
AppSearchSchema.StringPropertyConfig
.TOKENIZER_TYPE_PLAIN)
.build())
.build();
List<AppSearchSchema> schemas = Collections.singletonList(testSchema);
mAppSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document1 =
new GenericDocument.Builder<>("namespace", "id1", "type")
.setPropertyString("subject", "testPut example1")
.build();
GenericDocument document2 =
new GenericDocument.Builder<>("namespace", "id2", "type")
.setPropertyString("subject", "testPut example2")
.build();
GenericDocument document3 =
new GenericDocument.Builder<>("namespace", "id3", "type")
.setPropertyString("subject", "testPut 3")
.build();
mAppSearchImpl.putDocument(testPackageName, testDatabase, document1, mLogger);
mAppSearchImpl.putDocument(testPackageName, testDatabase, document2, mLogger);
mAppSearchImpl.putDocument(testPackageName, testDatabase, document3, mLogger);
// No query filters specified. package2 should only get its own documents back.
SearchSpec searchSpec =
new SearchSpec.Builder().setTermMatch(TermMatchType.Code.PREFIX_VALUE).build();
new SearchSpec.Builder()
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
.setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP)
.build();
String queryStr = "testPut e";
SearchResultPage searchResultPage =
mAppSearchImpl.query(
testPackageName,
testDatabase,
/*QueryExpression=*/ "",
searchSpec,
/*logger=*/ mLogger);
testPackageName, testDatabase, queryStr, searchSpec, /*logger=*/ mLogger);
assertThat(searchResultPage.getResults()).hasSize(1);
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document);
assertThat(searchResultPage.getResults()).hasSize(2);
// The ranking strategy is LIFO
assertThat(searchResultPage.getResults().get(0).getGenericDocument()).isEqualTo(document2);
assertThat(searchResultPage.getResults().get(1).getGenericDocument()).isEqualTo(document1);
SearchStats sStats = mLogger.mSearchStats;
@@ -368,17 +566,59 @@ public class AppSearchLoggerTest {
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.getTermCount()).isEqualTo(2);
assertThat(sStats.getQueryLength()).isEqualTo(queryStr.length());
assertThat(sStats.getFilteredNamespaceCount()).isEqualTo(1);
assertThat(sStats.getFilteredSchemaTypeCount()).isEqualTo(1);
assertThat(sStats.getCurrentPageReturnedResultCount()).isEqualTo(1);
assertThat(sStats.getCurrentPageReturnedResultCount()).isEqualTo(2);
assertThat(sStats.isFirstPage()).isTrue();
assertThat(sStats.getScoredDocumentCount()).isEqualTo(1);
assertThat(sStats.getRankingStrategy())
.isEqualTo(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP);
assertThat(sStats.getScoredDocumentCount()).isEqualTo(2);
assertThat(sStats.getResultWithSnippetsCount()).isEqualTo(0);
}
@Test
public void testLoggingStats_remove() throws Exception {
public void testLoggingStats_search_failure() throws Exception {
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
List<AppSearchSchema> schemas =
ImmutableList.of(
new AppSearchSchema.Builder("Type1").build(),
new AppSearchSchema.Builder("Type2").build());
mAppSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
SearchSpec searchSpec =
new SearchSpec.Builder()
.setTermMatch(TermMatchType.Code.PREFIX_VALUE)
.setRankingStrategy(SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP)
.addFilterPackageNames("anotherPackage")
.build();
mAppSearchImpl.query(
testPackageName,
testPackageName,
/* queryExpression= */ "",
searchSpec,
/*logger=*/ mLogger);
SearchStats sStats = mLogger.mSearchStats;
assertThat(sStats).isNotNull();
assertThat(sStats.getPackageName()).isEqualTo(testPackageName);
assertThat(sStats.getDatabase()).isEqualTo(testPackageName);
assertThat(sStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_SECURITY_ERROR);
}
@Test
public void testLoggingStats_remove_success() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
@@ -391,8 +631,8 @@ public class AppSearchLoggerTest {
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document =
@@ -406,12 +646,59 @@ public class AppSearchLoggerTest {
assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
// delete by namespace + id
assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.SINGLE_VALUE);
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(1);
}
@Test
public void testLoggingStats_removeByQuery() throws Exception {
public void testLoggingStats_remove_failure() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
final String testNamespace = "testNameSpace";
final String testId = "id";
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("type").build());
mAppSearchImpl.setSchema(
testPackageName,
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document =
new GenericDocument.Builder<>(testNamespace, testId, "type").build();
mAppSearchImpl.putDocument(testPackageName, testDatabase, document, /*logger=*/ null);
RemoveStats.Builder rStatsBuilder = new RemoveStats.Builder(testPackageName, testDatabase);
// We mainly want to check the status code in stats. So we don't need to inspect the
// exception here.
Assert.assertThrows(
AppSearchException.class,
() ->
mAppSearchImpl.remove(
testPackageName,
testDatabase,
testNamespace,
"invalidId",
rStatsBuilder));
RemoveStats rStats = rStatsBuilder.build();
assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_NOT_FOUND);
// delete by namespace + id
assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.SINGLE_VALUE);
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(0);
}
@Test
public void testLoggingStats_removeByQuery_success() throws Exception {
// Insert schema
final String testPackageName = "testPackage";
final String testDatabase = "testDatabase";
@@ -423,8 +710,8 @@ public class AppSearchLoggerTest {
testDatabase,
schemas,
/*visibilityStore=*/ null,
/*schemasNotPlatformSurfaceable=*/ Collections.emptyList(),
/*schemasPackageAccessible=*/ Collections.emptyMap(),
/*schemasNotDisplayedBySystem=*/ Collections.emptyList(),
/*schemasVisibleToPackages=*/ Collections.emptyMap(),
/*forceOverride=*/ false,
/*version=*/ 0);
GenericDocument document1 =
@@ -444,6 +731,7 @@ public class AppSearchLoggerTest {
assertThat(rStats.getPackageName()).isEqualTo(testPackageName);
assertThat(rStats.getDatabase()).isEqualTo(testDatabase);
assertThat(rStats.getStatusCode()).isEqualTo(AppSearchResult.RESULT_OK);
// delete by query
assertThat(rStats.getDeleteType()).isEqualTo(DeleteStatsProto.DeleteType.Code.QUERY_VALUE);
assertThat(rStats.getDeletedDocumentCount()).isEqualTo(2);

View File

@@ -46,7 +46,6 @@ public class SnippetTest {
PREFIX,
Collections.singletonMap(PREFIX + SCHEMA_TYPE, SCHEMA_TYPE_CONFIG_PROTO));
// TODO(tytytyww): Add tests for Double and Long Snippets.
@Test
public void testSingleStringSnippet() {
final String propertyKeyString = "content";
@@ -112,7 +111,6 @@ public class SnippetTest {
assertThat(match.getSnippet()).isEqualTo(window);
}
// TODO(tytytyww): Add tests for Double and Long Snippets.
@Test
public void testNoSnippets() {
final String propertyKeyString = "content";

View File

@@ -254,14 +254,25 @@ public class AppSearchStatsTest {
@Test
public void testAppSearchStats_SetSchemaStats() {
SchemaMigrationStats schemaMigrationStats =
new SchemaMigrationStats.Builder()
.setGetSchemaLatencyMillis(1)
.setQueryAndTransformLatencyMillis(2)
.setFirstSetSchemaLatencyMillis(3)
.setSecondSetSchemaLatencyMillis(4)
.setSaveDocumentLatencyMillis(5)
.setMigratedDocumentCount(6)
.setSavedDocumentCount(7)
.build();
int nativeLatencyMillis = 1;
int newTypeCount = 2;
int compatibleTypeChangeCount = 3;
int indexIncompatibleTypeChangeCount = 4;
int backwardsIncompatibleTypeChangeCount = 5;
final SetSchemaStats sStats =
SetSchemaStats sStats =
new SetSchemaStats.Builder(TEST_PACKAGE_NAME, TEST_DATA_BASE)
.setStatusCode(TEST_STATUS_CODE)
.setSchemaMigrationStats(schemaMigrationStats)
.setTotalLatencyMillis(TEST_TOTAL_LATENCY_MILLIS)
.setNativeLatencyMillis(nativeLatencyMillis)
.setNewTypeCount(newTypeCount)
@@ -274,6 +285,7 @@ public class AppSearchStatsTest {
assertThat(sStats.getPackageName()).isEqualTo(TEST_PACKAGE_NAME);
assertThat(sStats.getDatabase()).isEqualTo(TEST_DATA_BASE);
assertThat(sStats.getStatusCode()).isEqualTo(TEST_STATUS_CODE);
assertThat(sStats.getSchemaMigrationStats()).isEqualTo(schemaMigrationStats);
assertThat(sStats.getTotalLatencyMillis()).isEqualTo(TEST_TOTAL_LATENCY_MILLIS);
assertThat(sStats.getNativeLatencyMillis()).isEqualTo(nativeLatencyMillis);
assertThat(sStats.getNewTypeCount()).isEqualTo(newTypeCount);
@@ -284,6 +296,35 @@ public class AppSearchStatsTest {
.isEqualTo(backwardsIncompatibleTypeChangeCount);
}
@Test
public void testAppSearchStats_SchemaMigrationStats() {
int getSchemaLatency = 1;
int queryAndTransformLatency = 2;
int firstSetSchemaLatency = 3;
int secondSetSchemaLatency = 4;
int saveDocumentLatency = 5;
int migratedDocumentCount = 6;
int savedDocumentCount = 7;
SchemaMigrationStats sStats =
new SchemaMigrationStats.Builder()
.setGetSchemaLatencyMillis(getSchemaLatency)
.setQueryAndTransformLatencyMillis(queryAndTransformLatency)
.setFirstSetSchemaLatencyMillis(firstSetSchemaLatency)
.setSecondSetSchemaLatencyMillis(secondSetSchemaLatency)
.setSaveDocumentLatencyMillis(saveDocumentLatency)
.setMigratedDocumentCount(migratedDocumentCount)
.setSavedDocumentCount(savedDocumentCount)
.build();
assertThat(sStats.getGetSchemaLatencyMillis()).isEqualTo(getSchemaLatency);
assertThat(sStats.getQueryAndTransformLatencyMillis()).isEqualTo(queryAndTransformLatency);
assertThat(sStats.getFirstSetSchemaLatencyMillis()).isEqualTo(firstSetSchemaLatency);
assertThat(sStats.getSecondSetSchemaLatencyMillis()).isEqualTo(secondSetSchemaLatency);
assertThat(sStats.getSaveDocumentLatencyMillis()).isEqualTo(saveDocumentLatency);
assertThat(sStats.getMigratedDocumentCount()).isEqualTo(migratedDocumentCount);
assertThat(sStats.getSavedDocumentCount()).isEqualTo(savedDocumentCount);
}
@Test
public void testAppSearchStats_RemoveStats() {
int nativeLatencyMillis = 1;

View File

@@ -649,7 +649,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
protected class MockAppSearchManager implements IAppSearchManager {
protected Map<String, List<PackageIdentifier>> mSchemasPackageAccessible =
protected Map<String, List<PackageIdentifier>> mSchemasVisibleToPackages =
new ArrayMap<>(1);
private Map<String, Map<String, GenericDocument>> mDocumentMap = new ArrayMap<>(1);
@@ -659,19 +659,19 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
@Override
public void setSchema(String packageName, String databaseName, List<Bundle> schemaBundles,
List<String> schemasNotPlatformSurfaceable,
Map<String, List<Bundle>> schemasPackageAccessibleBundles, boolean forceOverride,
List<String> schemasNotDisplayedBySystem,
Map<String, List<Bundle>> schemasVisibleToPackagesBundles, boolean forceOverride,
int version, UserHandle userHandle, long binderCallStartTimeMillis,
IAppSearchResultCallback callback) throws RemoteException {
for (Map.Entry<String, List<Bundle>> entry :
schemasPackageAccessibleBundles.entrySet()) {
schemasVisibleToPackagesBundles.entrySet()) {
final String key = entry.getKey();
final List<PackageIdentifier> packageIdentifiers;
if (!mSchemasPackageAccessible.containsKey(key)) {
if (!mSchemasVisibleToPackages.containsKey(key)) {
packageIdentifiers = new ArrayList<>(entry.getValue().size());
mSchemasPackageAccessible.put(key, packageIdentifiers);
mSchemasVisibleToPackages.put(key, packageIdentifiers);
} else {
packageIdentifiers = mSchemasPackageAccessible.get(key);
packageIdentifiers = mSchemasVisibleToPackages.get(key);
}
for (int i = 0; i < entry.getValue().size(); i++) {
packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));