Add a broad try-catch to AppFunctionSchemaParser and attribute parsing for joinableType.
Also update the generated schema's names to be unique for package as in AppFunctionStaticMetadataParserImpl.
Change-Id: I6e011dc0441e2b095d8d3c880405d098b8f9cffa
Flag: EXEMPT Code not used yet
Test: atest AppsIndexerTests
Bug: 380729091
diff --git a/service/java/com/android/server/appsearch/appsindexer/AppFunctionSchemaParser.java b/service/java/com/android/server/appsearch/appsindexer/AppFunctionSchemaParser.java
index 1b7044f..e06414e 100644
--- a/service/java/com/android/server/appsearch/appsindexer/AppFunctionSchemaParser.java
+++ b/service/java/com/android/server/appsearch/appsindexer/AppFunctionSchemaParser.java
@@ -21,16 +21,19 @@
import android.app.appsearch.AppSearchSchema.LongPropertyConfig;
import android.app.appsearch.AppSearchSchema.PropertyConfig;
import android.app.appsearch.AppSearchSchema.StringPropertyConfig;
+import android.app.appsearch.util.LogUtil;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.util.ArrayMap;
+import android.util.Log;
import com.android.server.appsearch.appsindexer.appsearchtypes.AppFunctionStaticMetadata;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.util.Collections;
import java.util.Map;
import java.util.Objects;
@@ -41,23 +44,31 @@
/**
* This class parses the XSD file from an app's assets and creates AppSearch schemas from document
* types.
+ *
+ * <p>The generated {@link AppSearchSchema} objects are used to set the schema under the {@link
+ * AppSearchHelper#APP_DATABASE} database. Within the database, each {@link AppSearchSchema} is
+ * named dynamically to be unique to the app package name.
+ *
+ * <p>Note: The XSD file should be generated by the App Functions SDK and always define
+ * AppFunctionStaticMetadata document type.
*/
public class AppFunctionSchemaParser {
private static final String TAG = "AppSearchSchemaParser";
- private static final String TAG_DOCUMENT_TYPE = "xs:documentType";
- private static final String TAG_ELEMENT = "xs:element";
- private static final String APPFN_NAMESPACE_PREFIX = "appfn:";
- private static final String TAG_STRING_TYPE = "xs:string";
- private static final String TAG_LONG_TYPE = "xs:long";
- private static final String TAG_INT_TYPE = "xs:int";
- private static final String TAG_BOOLEAN_TYPE = "xs:boolean";
- private static final String ATTRIBUTE_INDEXING_TYPE = "indexingType";
- private static final String ATTRIBUTE_TOKENIZER_TYPE = "tokenizerType";
- private static final String ATTRIBUTE_CARDINALITY = "cardinality";
- private static final String ATTRIBUTE_SHOULD_INDEX_NESTED_PROPERTIES =
+ private static final String XML_TAG_DOCUMENT_TYPE = "xs:documentType";
+ private static final String XML_TAG_ELEMENT = "xs:element";
+ private static final String XML_APPFN_NAMESPACE_PREFIX = "appfn:";
+ private static final String XML_TAG_STRING_TYPE = "xs:string";
+ private static final String XML_TAG_LONG_TYPE = "xs:long";
+ private static final String XML_TAG_INT_TYPE = "xs:int";
+ private static final String XML_TAG_BOOLEAN_TYPE = "xs:boolean";
+ private static final String XML_ATTRIBUTE_INDEXING_TYPE = "indexingType";
+ private static final String XML_ATTRIBUTE_TOKENIZER_TYPE = "tokenizerType";
+ private static final String XML_ATTRIBUTE_JOINABLE_VALUE_TYPE = "joinableValueType";
+ private static final String XML_ATTRIBUTE_CARDINALITY = "cardinality";
+ private static final String XML_ATTRIBUTE_SHOULD_INDEX_NESTED_PROPERTIES =
"shouldIndexNestedProperties";
- private static final String ATTRIBUTE_NAME = "name";
- private static final String ATTRIBUTE_TYPE = "type";
+ private static final String XML_ATTRIBUTE_NAME = "name";
+ private static final String XML_ATTRIBUTE_TYPE = "type";
/**
* The maximum number of document types allowed in the XSD file. This is to prevent malicious
@@ -79,32 +90,55 @@
* Parses the XSD and create AppSearch schemas from document types.
*
* <p>The schema output isn't guaranteed to have valid dependencies, which can be caught during
- * a {@link SyncAppSearchSession#setSchema} call, however the parser will throw an exception if
- * the number of document types exceeds the maximum allowed or illegal types are encountered.
+ * a {@link SyncAppSearchSession#setSchema} call.
*
* @param packageManager The PackageManager used to access app resources.
* @param packageName The package name of the app whose assets contain the XSD file.
* @param assetFilePath The path to the XSD file within the app's assets.
- * @return A mapping of schema types to their corresponding {@link AppSearchSchema} objects.
+ * @return A mapping of schema types to their corresponding {@link AppSearchSchema} objects, or
+ * an empty map if there's an error during parsing or if the AppFunctionStaticMetadata
+ * document type is not found.
*/
@NonNull
public Map<String, AppSearchSchema> parseAndCreateSchemas(
@NonNull PackageManager packageManager,
@NonNull String packageName,
- @NonNull String assetFilePath)
- throws XmlPullParserException, NameNotFoundException, IOException {
+ @NonNull String assetFilePath) {
Objects.requireNonNull(packageManager);
Objects.requireNonNull(packageName);
Objects.requireNonNull(assetFilePath);
- AssetManager assetManager =
- packageManager.getResourcesForApplication(packageName).getAssets();
- InputStream xsdInputStream = assetManager.open(assetFilePath);
- return parseDocumentTypeAndCreateSchemas(xsdInputStream);
+ try {
+ AssetManager assetManager =
+ packageManager.getResourcesForApplication(packageName).getAssets();
+ InputStream xsdInputStream = assetManager.open(assetFilePath);
+ String appFunctionStaticMetadataType =
+ AppFunctionStaticMetadata.getSchemaNameForPackage(
+ packageName, /* schemaType= */ null);
+ Map<String, AppSearchSchema> schemas =
+ parseDocumentTypeAndCreateSchemas(packageName, xsdInputStream);
+ if (schemas.containsKey(appFunctionStaticMetadataType)) {
+ return schemas;
+ } else if (LogUtil.DEBUG) {
+ Log.d(TAG, "AppFunctionStaticMetadata schema not found.");
+ }
+ } catch (Exception ex) {
+ // The code parses an XSD file from another app's assets, using a broad try-catch to
+ // handle potential errors since the XML structure might be unpredictable.
+ Log.e(
+ TAG,
+ String.format(
+ "Failed to parse XSD from package '%s', asset file '%s'",
+ packageName, assetFilePath),
+ ex);
+ }
+ return Collections.emptyMap();
}
private Map<String, AppSearchSchema> parseDocumentTypeAndCreateSchemas(
- @NonNull InputStream xsdInputStream) throws XmlPullParserException, IOException {
+ @NonNull String packageName, @NonNull InputStream xsdInputStream)
+ throws XmlPullParserException, IOException {
+ Objects.requireNonNull(packageName);
Objects.requireNonNull(xsdInputStream);
Map<String, AppSearchSchema> schemas = new ArrayMap<>();
@@ -117,26 +151,30 @@
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
switch (parser.getEventType()) {
case XmlPullParser.START_TAG:
- if (TAG_DOCUMENT_TYPE.equals(parser.getName())) {
+ if (XML_TAG_DOCUMENT_TYPE.equals(parser.getName())) {
if (schemas.size() >= mMaxAllowedDocumentType) {
throw new IllegalStateException(
"Exceeded max allowed document types: "
+ mMaxAllowedDocumentType);
}
- String documentTypeName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
+ String documentTypeName =
+ parser.getAttributeValue(null, XML_ATTRIBUTE_NAME);
if (documentTypeName != null) {
- schemaBuilder = new AppSearchSchema.Builder(documentTypeName);
+ schemaBuilder =
+ new AppSearchSchema.Builder(
+ AppFunctionStaticMetadata.getSchemaNameForPackage(
+ packageName, documentTypeName));
}
- } else if (TAG_ELEMENT.equals(parser.getName()) && schemaBuilder != null) {
+ } else if (XML_TAG_ELEMENT.equals(parser.getName()) && schemaBuilder != null) {
AppSearchSchema.PropertyConfig propertyConfig =
- computePropertyConfigFromXsdType(parser);
+ computePropertyConfigFromXsdType(parser, packageName);
if (propertyConfig != null) schemaBuilder.addProperty(propertyConfig);
}
break;
case XmlPullParser.END_TAG:
- if (TAG_DOCUMENT_TYPE.equals(parser.getName())) {
+ if (XML_TAG_DOCUMENT_TYPE.equals(parser.getName())) {
if (schemaBuilder != null) {
AppSearchSchema schema = schemaBuilder.build();
schemas.put(schema.getSchemaType(), schema);
@@ -151,54 +189,65 @@
return schemas;
}
- private static PropertyConfig computePropertyConfigFromXsdType(@NonNull XmlPullParser parser)
+ private static PropertyConfig computePropertyConfigFromXsdType(
+ @NonNull XmlPullParser parser, @NonNull String packageName)
throws XmlPullParserException, IOException {
Objects.requireNonNull(parser);
- String name = parser.getAttributeValue(null, ATTRIBUTE_NAME);
- String type = parser.getAttributeValue(null, ATTRIBUTE_TYPE);
+ String name = parser.getAttributeValue(null, XML_ATTRIBUTE_NAME);
+ String type = parser.getAttributeValue(null, XML_ATTRIBUTE_TYPE);
if (name == null || type == null) return null;
int cardinality =
getAttributeIntOrDefault(
- parser, ATTRIBUTE_CARDINALITY, PropertyConfig.CARDINALITY_OPTIONAL);
+ parser, XML_ATTRIBUTE_CARDINALITY, PropertyConfig.CARDINALITY_OPTIONAL);
switch (type) {
- case TAG_STRING_TYPE:
+ case XML_TAG_STRING_TYPE:
return new StringPropertyConfig.Builder(name)
.setCardinality(cardinality)
.setIndexingType(
getAttributeIntOrDefault(
parser,
- ATTRIBUTE_INDEXING_TYPE,
+ XML_ATTRIBUTE_INDEXING_TYPE,
StringPropertyConfig.INDEXING_TYPE_NONE))
.setTokenizerType(
getAttributeIntOrDefault(
parser,
- ATTRIBUTE_TOKENIZER_TYPE,
+ XML_ATTRIBUTE_TOKENIZER_TYPE,
StringPropertyConfig.TOKENIZER_TYPE_NONE))
+ .setJoinableValueType(
+ getAttributeIntOrDefault(
+ parser,
+ XML_ATTRIBUTE_JOINABLE_VALUE_TYPE,
+ StringPropertyConfig.JOINABLE_VALUE_TYPE_NONE))
.build();
- case TAG_LONG_TYPE:
- case TAG_INT_TYPE:
+ case XML_TAG_LONG_TYPE:
+ case XML_TAG_INT_TYPE:
return new LongPropertyConfig.Builder(name)
.setCardinality(cardinality)
.setIndexingType(
getAttributeIntOrDefault(
parser,
- ATTRIBUTE_INDEXING_TYPE,
+ XML_ATTRIBUTE_INDEXING_TYPE,
LongPropertyConfig.INDEXING_TYPE_NONE))
.build();
- case TAG_BOOLEAN_TYPE:
+ case XML_TAG_BOOLEAN_TYPE:
return new BooleanPropertyConfig.Builder(name).setCardinality(cardinality).build();
default:
- if (type.contains(APPFN_NAMESPACE_PREFIX)) {
+ if (type.contains(XML_APPFN_NAMESPACE_PREFIX)) {
String localType = type.substring(type.indexOf(':') + 1);
- return new AppSearchSchema.DocumentPropertyConfig.Builder(name, localType)
+ return new AppSearchSchema.DocumentPropertyConfig.Builder(
+ name,
+ AppFunctionStaticMetadata.getSchemaNameForPackage(
+ packageName, localType))
.setCardinality(cardinality)
.setShouldIndexNestedProperties(
getAttributeBoolOrDefault(
- parser, ATTRIBUTE_SHOULD_INDEX_NESTED_PROPERTIES, true))
+ parser,
+ XML_ATTRIBUTE_SHOULD_INDEX_NESTED_PROPERTIES,
+ true))
.build();
}
throw new IllegalArgumentException("Unsupported type: " + type);
diff --git a/service/java/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImpl.java b/service/java/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImpl.java
index 27a8867..c6eab15 100644
--- a/service/java/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImpl.java
+++ b/service/java/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImpl.java
@@ -328,7 +328,9 @@
while (eventType != XmlPullParser.END_DOCUMENT) {
String tagName = parser.getName();
- if (eventType == XmlPullParser.START_TAG && schemas.containsKey(tagName)) {
+ String schemaName =
+ AppFunctionStaticMetadata.getSchemaNameForPackage(packageName, tagName);
+ if (eventType == XmlPullParser.START_TAG && schemas.containsKey(schemaName)) {
GenericDocument appFnMetadata =
parseXmlElementToGenericDocument(
parser,
@@ -401,7 +403,9 @@
parseXmlElementToGenericDocument(
parser,
packageName,
- ((DocumentPropertyConfig) propertyConfig).getSchemaType(),
+ getSchemaTypeWithoutPackage(
+ ((DocumentPropertyConfig) propertyConfig)
+ .getSchemaType()),
qualifiedPropertyNamesToPropertyConfig);
nestedDocumentValues
.computeIfAbsent(currentPropertyPath, k -> new ArrayList<>())
@@ -463,7 +467,7 @@
Map<String, PropertyConfig> propertyMap = new ArrayMap<>();
for (Map.Entry<String, AppSearchSchema> entry : schemaMap.entrySet()) {
- String schemaType = entry.getKey();
+ String schemaType = getSchemaTypeWithoutPackage(entry.getKey());
AppSearchSchema schema = entry.getValue();
List<AppSearchSchema.PropertyConfig> properties = schema.getProperties();
@@ -488,6 +492,17 @@
}
/**
+ * Returns the schema type without the package name suffix.
+ *
+ * <p>For example, if the schema name is "Person-com.example.app", this method will return
+ * "Person".
+ */
+ @NonNull
+ private static String getSchemaTypeWithoutPackage(@NonNull String schemaName) {
+ return Objects.requireNonNull(schemaName).substring(0, schemaName.indexOf('-'));
+ }
+
+ /**
* Adds primitive property values to the given {@link GenericDocument.Builder} based on the
* given {@link PropertyConfig}.
*
diff --git a/service/java/com/android/server/appsearch/appsindexer/package-info.java b/service/java/com/android/server/appsearch/appsindexer/package-info.java
new file mode 100644
index 0000000..a80c504
--- /dev/null
+++ b/service/java/com/android/server/appsearch/appsindexer/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 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.appsindexer;
+
+import android.app.appsearch.AppSearchSession;
+
+/**
+ * The package contains the implementation of the AppsIndexer used to index metadata about apps and
+ * app functions exposed by apps into AppSearch.
+ *
+ * <p>App function documents are indexed into AppSearch via {@link AppsIndexerImpl#doIncrementalUpdate} in a
+ * single {@link AppSearchHelper#APP_DATABASE} database. Within the database, each schema type is
+ * named dynamically to be unique to the app package name to control the schema visibility by the
+ * result of {@link android.content.pm.PackageManager#canPackageQuery}. This was preferred over
+ * defining one database per app because {@link AppSearchSession#setSchema} was a bottleneck for the
+ * inserting schemas into per app database.
+ */
diff --git a/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionSchemaParserTest.java b/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionSchemaParserTest.java
index 91ceccc..8ce59fd 100644
--- a/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionSchemaParserTest.java
+++ b/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionSchemaParserTest.java
@@ -16,7 +16,6 @@
package com.android.server.appsearch.appsindexer;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.when;
@@ -67,7 +66,7 @@
public void parse_singleType_withNoAttributes() throws Exception {
String xsd =
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
- + " <xs:documentType name=\"TestType\">"
+ + " <xs:documentType name=\"AppFunctionStaticMetadata\">"
+ " <xs:element name=\"name\" type=\"xs:string\" />"
+ " <xs:element name=\"age\" type=\"xs:int\" />"
+ " <xs:element name=\"isActive\" type=\"xs:boolean\" />"
@@ -80,9 +79,9 @@
mPackageManager, TEST_PACKAGE_NAME, TEST_XML_ASSET_FILE_PATH);
assertThat(schemas).hasSize(1);
- assertThat(schemas.get("TestType"))
+ assertThat(schemas.get("AppFunctionStaticMetadata-com.example.app"))
.isEqualTo(
- new AppSearchSchema.Builder("TestType")
+ new AppSearchSchema.Builder("AppFunctionStaticMetadata-com.example.app")
.addProperty(new StringPropertyConfig.Builder("name").build())
.addProperty(new LongPropertyConfig.Builder("age").build())
.addProperty(new BooleanPropertyConfig.Builder("isActive").build())
@@ -93,11 +92,13 @@
public void parse_singleType_withAttributes() throws Exception {
String xsd =
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
- + " <xs:documentType name=\"TestType\">"
+ + " <xs:documentType name=\"AppFunctionStaticMetadata\">"
+ " <xs:element name=\"name\" type=\"xs:string\" indexingType=\""
+ StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS
+ "\" tokenizerType=\""
+ StringPropertyConfig.TOKENIZER_TYPE_VERBATIM
+ + "\" joinableValueType=\""
+ + StringPropertyConfig.JOINABLE_VALUE_TYPE_QUALIFIED_ID
+ "\" />"
+ " <xs:element name=\"age\" type=\"xs:int\" indexingType=\""
+ LongPropertyConfig.INDEXING_TYPE_RANGE
@@ -114,9 +115,9 @@
mPackageManager, TEST_PACKAGE_NAME, TEST_XML_ASSET_FILE_PATH);
assertThat(schemas).hasSize(1);
- assertThat(schemas.get("TestType"))
+ assertThat(schemas.get("AppFunctionStaticMetadata-com.example.app"))
.isEqualTo(
- new AppSearchSchema.Builder("TestType")
+ new AppSearchSchema.Builder("AppFunctionStaticMetadata-com.example.app")
.addProperty(
new StringPropertyConfig.Builder("name")
.setIndexingType(
@@ -125,6 +126,9 @@
.setTokenizerType(
StringPropertyConfig
.TOKENIZER_TYPE_VERBATIM)
+ .setJoinableValueType(
+ StringPropertyConfig
+ .JOINABLE_VALUE_TYPE_QUALIFIED_ID)
.build())
.addProperty(
new LongPropertyConfig.Builder("age")
@@ -142,7 +146,7 @@
public void parse_multipleNestedTypes() throws Exception {
String xsd =
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
- + " <xs:documentType name=\"OuterType\">"
+ + " <xs:documentType name=\"AppFunctionStaticMetadata\">"
+ " <xs:element name=\"inner\" type=\"appfn:InnerType\" />"
+ " </xs:documentType>"
+ " <xs:documentType name=\"InnerType\">"
@@ -156,17 +160,17 @@
mPackageManager, TEST_PACKAGE_NAME, TEST_XML_ASSET_FILE_PATH);
assertThat(schemas).hasSize(2);
- assertThat(schemas.get("InnerType"))
+ assertThat(schemas.get("InnerType-com.example.app"))
.isEqualTo(
- new AppSearchSchema.Builder("InnerType")
+ new AppSearchSchema.Builder("InnerType-com.example.app")
.addProperty(new StringPropertyConfig.Builder("value").build())
.build());
- assertThat(schemas.get("OuterType"))
+ assertThat(schemas.get("AppFunctionStaticMetadata-com.example.app"))
.isEqualTo(
- new AppSearchSchema.Builder("OuterType")
+ new AppSearchSchema.Builder("AppFunctionStaticMetadata-com.example.app")
.addProperty(
new AppSearchSchema.DocumentPropertyConfig.Builder(
- "inner", "InnerType")
+ "inner", "InnerType-com.example.app")
.setShouldIndexNestedProperties(true)
.build())
.build());
@@ -188,19 +192,30 @@
+ "</xs:schema>";
setXmlInput(xsd);
- Exception e =
- assertThrows(
- IllegalStateException.class,
- () ->
- mParser.parseAndCreateSchemas(
- mPackageManager,
- TEST_PACKAGE_NAME,
- TEST_XML_ASSET_FILE_PATH));
- assertThat(e).hasMessageThat().contains("Exceeded max allowed document types: 2");
+ Map<String, AppSearchSchema> schemas =
+ mParser.parseAndCreateSchemas(
+ mPackageManager, TEST_PACKAGE_NAME, TEST_XML_ASSET_FILE_PATH);
+ assertThat(schemas).isEmpty();
}
@Test
- public void parse_unsupportedType_throwsException() throws Exception {
+ public void parse_unsupportedType_returnsEmptyMap() throws Exception {
+ String xsd =
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
+ + " <xs:documentType name=\"AppFunctionStaticMetadata\">"
+ + " <xs:element name=\"name\" type=\"xs:unsupportedType\" />"
+ + " </xs:documentType>"
+ + "</xs:schema>";
+ setXmlInput(xsd);
+
+ Map<String, AppSearchSchema> schemas =
+ mParser.parseAndCreateSchemas(
+ mPackageManager, TEST_PACKAGE_NAME, TEST_XML_ASSET_FILE_PATH);
+ assertThat(schemas).isEmpty();
+ }
+
+ @Test
+ public void parse_missingAppFunctionStaticMetadataType_returnsEmptyMap() throws Exception {
String xsd =
"<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">"
+ " <xs:documentType name=\"TestType\">"
@@ -209,15 +224,10 @@
+ "</xs:schema>";
setXmlInput(xsd);
- Exception e =
- assertThrows(
- IllegalArgumentException.class,
- () ->
- mParser.parseAndCreateSchemas(
- mPackageManager,
- TEST_PACKAGE_NAME,
- TEST_XML_ASSET_FILE_PATH));
- assertThat(e).hasMessageThat().contains("Unsupported type: xs:unsupportedType");
+ Map<String, AppSearchSchema> schemas =
+ mParser.parseAndCreateSchemas(
+ mPackageManager, TEST_PACKAGE_NAME, TEST_XML_ASSET_FILE_PATH);
+ assertThat(schemas).isEmpty();
}
private void setXmlInput(String xml) throws IOException {
diff --git a/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImplTest.java b/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImplTest.java
index e92bd31..05d8b5b 100644
--- a/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImplTest.java
+++ b/testing/appsindexertests/src/com/android/server/appsearch/appsindexer/AppFunctionStaticMetadataParserImplTest.java
@@ -48,7 +48,7 @@
private static final String TEST_XML_ASSET_FILE_PATH = "app_functions.xml";
private static final Map<String, AppSearchSchema> TEST_SCHEMAS =
Map.of(
- "AppFunctionStaticMetadata",
+ "AppFunctionStaticMetadata-com.example.app",
new AppSearchSchema.Builder("AppFunctionStaticMetadata-com.example.app")
.addProperty(
new AppSearchSchema.StringPropertyConfig.Builder("functionId")
@@ -63,10 +63,10 @@
.addProperty(
new AppSearchSchema.DocumentPropertyConfig.Builder(
"appFunctionParameterMetadata",
- "AppFunctionParameterMetadata")
+ "AppFunctionParameterMetadata-com.example.app")
.build())
.build(),
- "AppFunctionParameterMetadata",
+ "AppFunctionParameterMetadata-com.example.app",
new AppSearchSchema.Builder("AppFunctionParameterMetadata-com.example.app")
.addProperty(
new AppSearchSchema.StringPropertyConfig.Builder(