Snap for 8820681 from 65867ee55adf92723851186b9f88dc9e6847aa9b to mainline-go-appsearch-release
Change-Id: I78e7f808d34b7727d4977343ca6a75987b02c7e4
diff --git a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
index 820fd95..24d1249 100644
--- a/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
+++ b/hostsidetests/appcompat/strictjavapackages/src/android/compat/sjp/cts/StrictJavaPackagesTest.java
@@ -83,6 +83,7 @@
private static ImmutableList<String> sSystemserverclasspathJars;
private static ImmutableList<String> sSharedLibJars;
private static ImmutableList<SharedLibraryInfo> sSharedLibs;
+ private static ImmutableMultimap<String, String> sSharedLibsPathsToName;
private static ImmutableMultimap<String, String> sJarsToClasses;
private static ImmutableMultimap<String, String> sJarsToFiles;
@@ -795,6 +796,13 @@
.filter(file -> !file.contains("GmsCore"))
.filter(file -> !file.contains("com.google.android.gms"))
.collect(ImmutableList.toImmutableList());
+ final ImmutableSetMultimap.Builder<String, String> sharedLibsPathsToName =
+ ImmutableSetMultimap.builder();
+ sSharedLibs.forEach(sharedLibraryInfo -> {
+ sharedLibraryInfo.paths.forEach(path ->
+ sharedLibsPathsToName.putAll(path, sharedLibraryInfo.name));
+ });
+ sSharedLibsPathsToName = sharedLibsPathsToName.build();
final ImmutableSetMultimap.Builder<String, String> jarsToFiles =
ImmutableSetMultimap.builder();
@@ -1038,17 +1046,17 @@
// WARNING: Do not add more exceptions here, no androidx should be in bootclasspath.
// See go/androidx-api-guidelines#module-naming for more details.
final ImmutableMap<String, ImmutableSet<String>>
- LegacyExemptAndroidxSharedLibsJarToClasses =
+ LegacyExemptAndroidxSharedLibsNamesToClasses =
new ImmutableMap.Builder<String, ImmutableSet<String>>()
- .put("/vendor/framework/androidx.camera.extensions.impl.jar",
+ .put("androidx.camera.extensions.impl",
ImmutableSet.of("Landroidx/camera/extensions/impl/"))
- .put("/system_ext/framework/androidx.window.extensions.jar",
+ .put("androidx.window.extensions",
ImmutableSet.of("Landroidx/window/common/", "Landroidx/window/extensions/",
"Landroidx/window/util/"))
- .put("/system_ext/framework/androidx.window.sidecar.jar",
+ .put("androidx.window.sidecar",
ImmutableSet.of("Landroidx/window/common/", "Landroidx/window/sidecar",
"Landroidx/window/util"))
- .put("/vendor/framework/com.google.android.camera.experimental2020_midyear.jar",
+ .put("com.google.android.camera.experimental2020_midyear",
ImmutableSet.of("Landroidx/annotation"))
.build();
assertWithMessage("There must not be any androidx classes on the "
@@ -1057,7 +1065,7 @@
.that(sJarsToClasses.entries().stream()
.filter(e -> e.getValue().startsWith("Landroidx/"))
.filter(e -> !isLegacyAndroidxDependency(
- LegacyExemptAndroidxSharedLibsJarToClasses, e.getKey(), e.getValue()))
+ LegacyExemptAndroidxSharedLibsNamesToClasses, e.getKey(), e.getValue()))
.collect(Collectors.toList())
).isEmpty();
}
@@ -1103,11 +1111,12 @@
}
private boolean isLegacyAndroidxDependency(
- ImmutableMap<String, ImmutableSet<String>> legacyExemptAndroidxSharedLibsJarToClasses,
- String jar, String className) {
- return legacyExemptAndroidxSharedLibsJarToClasses.containsKey(jar)
- && legacyExemptAndroidxSharedLibsJarToClasses.get(jar).stream().anyMatch(
- v -> className.startsWith(v));
+ ImmutableMap<String, ImmutableSet<String>> legacyExemptAndroidxSharedLibsNamesToClasses,
+ String path, String className) {
+ return sSharedLibsPathsToName.get(path).stream()
+ .filter(legacyExemptAndroidxSharedLibsNamesToClasses::containsKey)
+ .flatMap(name -> legacyExemptAndroidxSharedLibsNamesToClasses.get(name).stream())
+ .anyMatch(className::startsWith);
}
private String[] collectApkInApexPaths() {
diff --git a/hostsidetests/securitybulletin/res/cve_2021_39623.ogg b/hostsidetests/securitybulletin/res/cve_2021_39623.ogg
new file mode 100644
index 0000000..1992a17
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2021_39623.ogg
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp
new file mode 100644
index 0000000..50662fd
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/Android.bp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+ name: "CVE-2021-39623",
+ defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+ srcs: [
+ "poc.cpp",
+ ],
+ header_libs: [
+ "libmediametrics_headers",
+ ],
+ shared_libs: [
+ "libstagefright",
+ "libdatasource",
+ "libutils",
+ ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp
new file mode 100644
index 0000000..d9e38ba
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2021-39623/poc.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include "../includes/common.h"
+#include <datasource/DataSourceFactory.h>
+#include <dlfcn.h>
+#include <gui/SurfaceComposerClient.h>
+#include <media/IMediaHTTPService.h>
+#include <media/stagefright/InterfaceUtils.h>
+#include <media/stagefright/MediaCodecList.h>
+#include <media/stagefright/MediaExtractorFactory.h>
+#include <media/stagefright/SimpleDecodingSource.h>
+#include <sys/mman.h>
+
+typedef void *(*mmap_t)(void *, size_t, int, int, int, off_t);
+mmap_t real_mmap = nullptr;
+
+using namespace android;
+
+bool testInProgress = false;
+constexpr size_t kTargetBufferSize = 32768;
+struct sigaction new_action, old_action;
+void sigsegv_handler(int signum, siginfo_t *info, void *context) {
+ if (testInProgress && info->si_signo == SIGSEGV) {
+ (*old_action.sa_sigaction)(signum, info, context);
+ return;
+ }
+ exit(EXIT_FAILURE);
+}
+
+void *mmap(void *addr, size_t length, int prot, int flags, int fd,
+ off_t offset) {
+ real_mmap = (mmap_t)dlsym(RTLD_NEXT, "mmap");
+ if (!real_mmap) {
+ exit(EXIT_FAILURE);
+ }
+ if (length == kTargetBufferSize) {
+ char *tmp_ptr = (char *)real_mmap(addr, length + PAGE_SIZE, prot,
+ flags | MAP_ANONYMOUS, -1, offset);
+ mprotect(tmp_ptr + length, PAGE_SIZE, PROT_NONE);
+ return tmp_ptr;
+ }
+ return real_mmap(addr, length, prot, flags, fd, offset);
+}
+
+int main(int argc, char **argv) {
+ FAIL_CHECK(argc > 1);
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+ new_action.sa_sigaction = sigsegv_handler;
+ sigaction(SIGSEGV, &new_action, &old_action);
+
+ sp<DataSource> dataSource = DataSourceFactory::getInstance()->CreateFromURI(
+ nullptr /* httpService */, argv[1]);
+ FAIL_CHECK(dataSource);
+
+ sp<IMediaExtractor> extractor = MediaExtractorFactory::Create(dataSource);
+ FAIL_CHECK(extractor);
+
+ sp<MediaSource> mediaSource =
+ CreateMediaSourceFromIMediaSource(extractor->getTrack(0));
+ FAIL_CHECK(mediaSource);
+
+ sp<MediaSource> rawSource = SimpleDecodingSource::Create(
+ mediaSource, MediaCodecList::kPreferSoftwareCodecs, nullptr, nullptr,
+ false);
+ FAIL_CHECK(rawSource);
+
+ status_t err = rawSource->start();
+ FAIL_CHECK(err == OK);
+
+ MediaSource::ReadOptions options = {};
+ MediaBufferBase *buffer = nullptr;
+
+ testInProgress = true;
+ rawSource->read(&buffer, &options);
+ testInProgress = false;
+ if (buffer) {
+ buffer->release();
+ buffer = nullptr;
+ }
+ options.clearSeekTo();
+ options.setSeekTo(0);
+ rawSource->stop();
+ return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java
new file mode 100644
index 0000000..9ab3f08
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/CVE_2021_39623.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2022 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 android.security.cts;
+
+import android.platform.test.annotations.AsbSecurityTest;
+
+import com.android.compatibility.common.util.CrashUtils;
+import com.android.compatibility.common.util.CrashUtils.Config.BacktraceFilterPattern;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class CVE_2021_39623 extends SecurityTestCase {
+
+ /**
+ * b/194105348
+ * Vulnerability Behaviour: SIGSEGV in self
+ * Vulnerable Library: libstagefright (As per AOSP code)
+ * Vulnerable Function: doRead (As per AOSP code)
+ */
+ @AsbSecurityTest(cveBugId = 194105348)
+ @Test
+ public void testPocCVE_2021_39623() throws Exception {
+ String binaryName = "CVE-2021-39623";
+ AdbUtils.pocConfig testConfig = new AdbUtils.pocConfig(binaryName, getDevice());
+ testConfig.config = new CrashUtils.Config().setProcessPatterns(binaryName)
+ .setBacktraceIncludes(new BacktraceFilterPattern("libstagefright",
+ "android::SimpleDecodingSource::doRead"));
+ String signals[] = {CrashUtils.SIGSEGV};
+ testConfig.config.setSignals(signals);
+ testConfig.inputFilesDestination = AdbUtils.TMP_PATH;
+ String inputFiles[] = {"cve_2021_39623.ogg"};
+ testConfig.inputFiles = Arrays.asList(inputFiles);
+ testConfig.arguments = AdbUtils.TMP_PATH + inputFiles[0];
+ AdbUtils.runPocAssertNoCrashesNotVulnerable(testConfig);
+ }
+}
diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java
index 70b68b4..affdaa8 100644
--- a/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java
+++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/AppSearchSessionCtsTestBase.java
@@ -676,6 +676,7 @@
.build())
.build();
mDb1.setSchemaAsync(new SetSchemaRequest.Builder().addSchemas(schema).build()).get();
+
// Creates a large batch of Documents, since we have max document size in Framework which is
// 512KiB, we will create 1KiB * 4000 docs = 4MiB total size > 1MiB binder transaction limit
char[] chars = new char[1024]; // 1KiB
@@ -3851,4 +3852,104 @@
documents = convertSearchResultsToDocuments(searchResults);
assertThat(documents).containsExactly(inEmail1);
}
+
+ @Test
+ public void testSetSchemaWithIncompatibleNestedSchema() throws Exception {
+ // 1. Set the original schema. This should succeed without any problems.
+ AppSearchSchema originalNestedSchema =
+ new AppSearchSchema.Builder("TypeA")
+ .addProperty(
+ new StringPropertyConfig.Builder("prop1")
+ .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL)
+ .build())
+ .build();
+ SetSchemaRequest originalRequest =
+ new SetSchemaRequest.Builder().addSchemas(originalNestedSchema).build();
+ mDb1.setSchemaAsync(originalRequest).get();
+
+ // 2. Set a new schema with a new type that refers to "TypeA" and an incompatible change to
+ // "TypeA". This should fail.
+ AppSearchSchema newNestedSchema =
+ new AppSearchSchema.Builder("TypeA")
+ .addProperty(
+ new StringPropertyConfig.Builder("prop1")
+ .setCardinality(PropertyConfig.CARDINALITY_REQUIRED)
+ .build())
+ .build();
+ AppSearchSchema newSchema =
+ new AppSearchSchema.Builder("TypeB")
+ .addProperty(
+ new AppSearchSchema.DocumentPropertyConfig.Builder("prop2", "TypeA")
+ .build())
+ .build();
+ final SetSchemaRequest newRequest =
+ new SetSchemaRequest.Builder().addSchemas(newNestedSchema, newSchema).build();
+ Throwable throwable =
+ assertThrows(ExecutionException.class, () -> mDb1.setSchemaAsync(newRequest).get())
+ .getCause();
+ assertThat(throwable).isInstanceOf(AppSearchException.class);
+ AppSearchException exception = (AppSearchException) throwable;
+ assertThat(exception.getResultCode()).isEqualTo(RESULT_INVALID_SCHEMA);
+ assertThat(exception).hasMessageThat().contains("Schema is incompatible.");
+ assertThat(exception).hasMessageThat().contains("Incompatible types: {TypeA}");
+
+ // 3. Now set that same set of schemas but with forceOverride=true. This should succeed.
+ SetSchemaRequest newRequestForced =
+ new SetSchemaRequest.Builder()
+ .addSchemas(newNestedSchema, newSchema)
+ .setForceOverride(true)
+ .build();
+ mDb1.setSchemaAsync(newRequestForced).get();
+ }
+
+ @Test
+ public void testEmojiSnippet() throws Exception {
+ // Schema registration
+ mDb1.setSchemaAsync(
+ new SetSchemaRequest.Builder().addSchemas(AppSearchEmail.SCHEMA).build())
+ .get();
+
+ // String: "Luca Brasi sleeps with the 🐟🐟🐟."
+ // ^ ^ ^ ^ ^ ^ ^ ^ ^
+ // UTF8 idx: 0 5 11 18 23 27 3135 39
+ // UTF16 idx: 0 5 11 18 23 27 2931 33
+ // Breaks into segments: "Luca", "Brasi", "sleeps", "with", "the", "🐟", "🐟"
+ // and "🐟".
+ // Index a document to instance 1.
+ String sicilianMessage = "Luca Brasi sleeps with the 🐟🐟🐟.";
+ AppSearchEmail inEmail1 =
+ new AppSearchEmail.Builder("namespace", "uri1").setBody(sicilianMessage).build();
+ checkIsBatchResultSuccess(
+ mDb1.putAsync(
+ new PutDocumentsRequest.Builder().addGenericDocuments(inEmail1).build()));
+
+ AppSearchEmail inEmail2 =
+ new AppSearchEmail.Builder("namespace", "uri2")
+ .setBody("Some other content.")
+ .build();
+ checkIsBatchResultSuccess(
+ mDb1.putAsync(
+ new PutDocumentsRequest.Builder().addGenericDocuments(inEmail2).build()));
+
+ // Query for "🐟"
+ SearchResultsShim searchResults =
+ mDb1.search(
+ "🐟",
+ new SearchSpec.Builder()
+ .setTermMatch(SearchSpec.TERM_MATCH_PREFIX)
+ .setSnippetCount(1)
+ .setSnippetCountPerProperty(1)
+ .build());
+ List<SearchResult> page = searchResults.getNextPageAsync().get();
+ assertThat(page).hasSize(1);
+ assertThat(page.get(0).getGenericDocument()).isEqualTo(inEmail1);
+ List<SearchResult.MatchInfo> matches = page.get(0).getMatchInfos();
+ assertThat(matches).hasSize(1);
+ assertThat(matches.get(0).getPropertyPath()).isEqualTo("body");
+ assertThat(matches.get(0).getFullText()).isEqualTo(sicilianMessage);
+ assertThat(matches.get(0).getExactMatch()).isEqualTo("🐟");
+ if (mDb1.getFeatures().isFeatureSupported(Features.SEARCH_RESULT_MATCH_INFO_SUBMATCH)) {
+ assertThat(matches.get(0).getSubmatch()).isEqualTo("🐟");
+ }
+ }
}
diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java
index 5dd2eac..0bfa693 100644
--- a/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java
+++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/GenericDocumentCtsTest.java
@@ -576,6 +576,30 @@
}
@Test
+ public void testNestedProperties_buildBlankPaths() {
+ Exception e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new GenericDocument.Builder<>("namespace", "id1", "schema1")
+ .setPropertyString("", "foo"));
+ assertThat(e.getMessage()).isEqualTo("Property name cannot be blank.");
+
+ e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ new GenericDocument.Builder<>("namespace", "id1", "schema1")
+ .setPropertyDocument(
+ "propDoc",
+ new GenericDocument.Builder<>(
+ "namespace", "id2", "schema1")
+ .setPropertyString("", "Bat", "Hawk")
+ .build()));
+ assertThat(e.getMessage()).isEqualTo("Property name cannot be blank.");
+ }
+
+ @Test
public void testNestedProperties_invalidPaths() {
GenericDocument doc =
new GenericDocument.Builder<>("namespace", "id1", "schema1")
@@ -592,25 +616,28 @@
.build())
.build();
- // Some paths are invalid because they don't apply to the given document --- these should
+ // These paths are invalid because they don't apply to the given document --- these should
// return null. It's not the querier's fault.
assertThat(doc.getPropertyStringArray("propString.propInts")).isNull();
assertThat(doc.getPropertyStringArray("propDocs.propFoo")).isNull();
assertThat(doc.getPropertyStringArray("propDocs.propNestedString.propFoo")).isNull();
+ }
- // Some paths are invalid because they are malformed. These throw an exception --- the
- // querier shouldn't provide such paths.
- assertThrows(
- IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[0"));
- assertThrows(
- IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[0.]"));
- assertThrows(
- IllegalArgumentException.class,
- () -> doc.getPropertyStringArray("propString[banana]"));
- assertThrows(
- IllegalArgumentException.class, () -> doc.getPropertyStringArray("propString[-1]"));
- assertThrows(
- IllegalArgumentException.class, () -> doc.getPropertyStringArray("propDocs[0]cat"));
+ @Test
+ public void testNestedProperties_arrayTypesInvalidPath() {
+ GenericDocument doc = new GenericDocument.Builder<>("namespace", "id1", "schema1").build();
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyString("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDocument("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBoolean("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDouble("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyLong("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBytes("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyStringArray("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDocumentArray("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBooleanArray("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyDoubleArray("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyLongArray("."));
+ assertThrows(IllegalArgumentException.class, () -> doc.getPropertyBytesArray("."));
}
@Test
diff --git a/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java b/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java
index 71822ca..47337ca 100644
--- a/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java
+++ b/tests/appsearch/src/com/android/cts/appsearch/external/app/GlobalSearchSessionCtsTestBase.java
@@ -1641,6 +1641,11 @@
@Test
public void testAddObserver_schemaChange_added() throws Exception {
+ assumeTrue(
+ mDb1.getFeatures()
+ .isFeatureSupported(
+ Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
+
// Register an observer
TestObserverCallback observer = new TestObserverCallback();
mGlobalSearchSession.registerObserverCallback(
@@ -1688,6 +1693,11 @@
@Test
public void testAddObserver_schemaChange_removed() throws Exception {
+ assumeTrue(
+ mDb1.getFeatures()
+ .isFeatureSupported(
+ Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
+
// Add a schema type
mDb1.setSchemaAsync(
new SetSchemaRequest.Builder()
@@ -1723,6 +1733,11 @@
@Test
public void testAddObserver_schemaChange_contents() throws Exception {
+ assumeTrue(
+ mDb1.getFeatures()
+ .isFeatureSupported(
+ Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
+
// Add a schema
mDb1.setSchemaAsync(
new SetSchemaRequest.Builder()
@@ -1794,6 +1809,11 @@
@Test
public void testAddObserver_schemaChange_contents_skipBySpec() throws Exception {
+ assumeTrue(
+ mDb1.getFeatures()
+ .isFeatureSupported(
+ Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
+
// Add a schema
mDb1.setSchemaAsync(
new SetSchemaRequest.Builder()
@@ -1862,6 +1882,11 @@
@Test
public void testRegisterObserver_schemaMigration() throws Exception {
+ assumeTrue(
+ mDb1.getFeatures()
+ .isFeatureSupported(
+ Features.GLOBAL_SEARCH_SESSION_REGISTER_OBSERVER_CALLBACK));
+
// Add a schema with two types
mDb1.setSchemaAsync(
new SetSchemaRequest.Builder()
diff --git a/tests/framework/base/windowmanager/Android.bp b/tests/framework/base/windowmanager/Android.bp
index 168ee3f..b786d83 100644
--- a/tests/framework/base/windowmanager/Android.bp
+++ b/tests/framework/base/windowmanager/Android.bp
@@ -67,6 +67,7 @@
"cts-wm-overlayapp-base",
"cts-wm-shared",
"platform-compat-test-rules",
+ "cts_window_jetpack_utils",
],
test_suites: [
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index 39c3d3e..1a86422 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -38,6 +38,8 @@
android:enableOnBackInvokedCallback="true"
android:testOnly="true">
<uses-library android:name="android.test.runner"/>
+ <uses-library android:name="androidx.window.extensions"
+ android:required="false" />
<activity android:name="android.server.wm.ActivityManagerTestBase$ConfigChangeHandlingActivity"
android:resizeableActivity="true"
diff --git a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java
index d12b7c1d..477cc8d 100644
--- a/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java
+++ b/tests/framework/base/windowmanager/jetpack/src/android/server/wm/jetpack/utils/ActivityEmbeddingUtil.java
@@ -16,6 +16,7 @@
package android.server.wm.jetpack.utils;
+import static android.server.wm.jetpack.utils.ExtensionUtil.assumeExtensionSupportedDevice;
import static android.server.wm.jetpack.utils.ExtensionUtil.getWindowExtensions;
import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.getActivityBounds;
import static android.server.wm.jetpack.utils.WindowManagerJetpackTestBase.getMaximumActivityBounds;
@@ -28,6 +29,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import android.app.Activity;
import android.content.ComponentName;
@@ -51,6 +53,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.function.Predicate;
/**
@@ -447,6 +450,13 @@
}
}
+ public static void assumeActivityEmbeddingSupportedDevice() {
+ assumeExtensionSupportedDevice();
+ assumeTrue("Device does not support ActivityEmbedding",
+ Objects.requireNonNull(getWindowExtensions())
+ .getActivityEmbeddingComponent() != null);
+ }
+
private static void assertSplitInfoTopSplitIsCorrect(@NonNull List<SplitInfo> splitInfoList,
@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) {
assertFalse("Split info callback should not be empty", splitInfoList.isEmpty());
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
index 385a5af..c13c4ee 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/TaskFragmentTrustedModeTest.java
@@ -18,6 +18,7 @@
import static android.server.wm.WindowManagerState.STATE_RESUMED;
import static android.server.wm.jetpack.second.Components.SECOND_UNTRUSTED_EMBEDDING_ACTIVITY;
+import static android.server.wm.jetpack.utils.ActivityEmbeddingUtil.assumeActivityEmbeddingSupportedDevice;
import static com.google.common.truth.Truth.assertThat;
@@ -39,6 +40,7 @@
import androidx.annotation.NonNull;
+import org.junit.Before;
import org.junit.Test;
/**
@@ -52,6 +54,13 @@
private final ComponentName mTranslucentActivity = new ComponentName(mContext,
TranslucentActivity.class);
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ assumeActivityEmbeddingSupportedDevice();
+ }
+
/**
* Verifies the visibility of a task fragment that has overlays on top of activities embedded
* in untrusted mode when there is an overlay over the task fragment.
diff --git a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
index 2508845..8da22f3 100644
--- a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
@@ -41,6 +41,7 @@
import java.util.List;
import java.util.UUID;
import org.junit.Assume;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
@@ -58,6 +59,11 @@
@Rule
public final TestName mTestName = new TestName();
+ @Before
+ public void isPerformanceClassCandidate() {
+ Utils.assumeDeviceMeetsPerformanceClassPreconditions();
+ }
+
static {
mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_AVC);
mMimeSecureSupport.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
diff --git a/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
index bbe26dc..2ee8b3b 100644
--- a/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/VideoCodecRequirementsTest.java
@@ -21,12 +21,14 @@
import static android.mediapc.cts.CodecTestBase.SELECT_VIDEO;
import static android.mediapc.cts.CodecTestBase.getMimesOfAvailableCodecs;
import static android.mediapc.cts.CodecTestBase.selectHardwareCodecs;
+import static org.junit.Assert.assertTrue;
import android.media.MediaCodec;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint;
import android.media.MediaFormat;
import android.mediapc.cts.common.PerformanceClassEvaluator;
+import android.mediapc.cts.common.Utils;
import android.util.Log;
import androidx.test.filters.LargeTest;
import com.android.compatibility.common.util.CddTest;
@@ -35,6 +37,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
@@ -47,6 +50,11 @@
@Rule
public final TestName mTestName = new TestName();
+ @Before
+ public void isPerformanceClassCandidate() {
+ Utils.assumeDeviceMeetsPerformanceClassPreconditions();
+ }
+
private Set<String> get4k60HwCodecSet(boolean isEncoder) throws IOException {
Set<String> codecSet = new HashSet<>();
Set<String> codecMediaTypes = getMimesOfAvailableCodecs(SELECT_VIDEO, SELECT_HARDWARE);
@@ -60,6 +68,7 @@
codec.getCodecInfo().getCapabilitiesForType(codecMediaType);
List<PerformancePoint> pps =
capabilities.getVideoCapabilities().getSupportedPerformancePoints();
+ assertTrue(hwVideoCodec + " doesn't advertise performance points", pps.size() > 0);
for (PerformancePoint pp : pps) {
if (pp.covers(PP4k60)) {
codecSet.add(hwVideoCodec);
diff --git a/tests/tests/media/common/src/android/media/cts/CodecState.java b/tests/tests/media/common/src/android/media/cts/CodecState.java
index 13e56f8..3565fc8 100644
--- a/tests/tests/media/common/src/android/media/cts/CodecState.java
+++ b/tests/tests/media/common/src/android/media/cts/CodecState.java
@@ -358,7 +358,7 @@
return null;
}
- if (mIsTunneled && !mIsAudio) {
+ if (mIsTunneled) {
if (mFirstSampleTimeUs == -1) {
mFirstSampleTimeUs = sampleTime;
}
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index dfc8031..d785d96 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -284,5 +284,6 @@
<!-- b/237035040 -->
<option name="compatibility:exclude-filter" value="CtsGraphicsTestCases android.graphics.cts.ImageDecoderTest#testDecode10BitHeifWithLowRam" />
+ <option name="compatibility:exclude-filter" value="CtsGraphicsTestCases[instant] android.graphics.cts.ImageDecoderTest#testDecode10BitHeifWithLowRam" />
</configuration>