Merge "Always set secure FRP setting on user 0" into rvc-dev
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 14bbc39..8b45f84 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -209,7 +209,7 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
- <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive:android.software.lockscreen_disabled" />
+ <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive:android.hardware.type.television:android.software.lockscreen_disabled" />
<meta-data android:name="test_required_features"
android:value="android.software.device_admin" />
</activity>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index b1e0388..b898bc9 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -2356,7 +2356,7 @@
<!-- Strings for CA cert installation via intent test -->
<string name="cacert_install_via_intent">CA Cert install via intent</string>
<string name="cacert_install_via_intent_title">This test attempts to install a CA certificate via an intent.</string>
- <string name="cacert_install_via_intent_info">Attempt installing a CA certificate via an intent, which should fail. If you see a dialog redirecting the user to Settings for installing the certificate, the test passed. If a any other dialog comes up, the test failed.</string>
+ <string name="cacert_install_via_intent_info">Attempt installing a CA certificate via an intent, which should not be possible. Tapping Go should show a dialog telling the user that CA certificates can put their privacy at risk and must be installed via Settings. If a any other dialog comes up, the test failed.</string>
<!-- Strings for Widget -->
<string name="widget_framework_test">Widget Framework Test</string>
@@ -3983,7 +3983,7 @@
Please press \'Create uninitialized user\' to create a user that is not set up. Then press the
\'Set restriction\' button to set the user restriction.
Then press \'Go\' to open \'Multiple users\' setting. \n
- Click the Settings icon adjacent to the managed user.\n\n
+ Click the managed user to open settings.\n\n
Mark this test as passed if:\n\n
- \"Delete User\" is disabled.\n
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
index 62892d6..1a829f2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkSuggestionTestCase.java
@@ -127,6 +127,7 @@
mNetworkSuggestionBuilder.setWpa3Passphrase(mPsk);
}
}
+ mNetworkSuggestionBuilder.setIsMetered(false);
return mNetworkSuggestionBuilder.build();
}
diff --git a/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java b/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
index 11a1ae0..bea7506 100644
--- a/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
+++ b/hostsidetests/adb/src/android/adb/cts/AdbHostTest.java
@@ -59,8 +59,13 @@
File check_ms_os_desc = copyResourceToTempFile("/check_ms_os_desc");
check_ms_os_desc.setExecutable(true);
+ String serial = getDevice().getSerialNumber();
+ if (serial.startsWith("emulator-")) {
+ return;
+ }
+
ProcessBuilder pb = new ProcessBuilder(check_ms_os_desc.getAbsolutePath());
- pb.environment().put("ANDROID_SERIAL", getDevice().getSerialNumber());
+ pb.environment().put("ANDROID_SERIAL", serial);
pb.redirectOutput(ProcessBuilder.Redirect.PIPE);
pb.redirectErrorStream(true);
Process p = pb.start();
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
index 3900d4a..f939b17 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/CorruptApkTests.java
@@ -111,8 +111,10 @@
device.uninstallPackage("com.android.appsecurity.b71360999");
device.uninstallPackage("com.android.appsecurity.b71361168");
device.uninstallPackage("com.android.appsecurity.b79488511");
- device.uninstallPackage(CORRUPT_APK_PACKAGE_NAME);
+ // WARNING: PlatformCompat overrides for package parsing changes must be reset before the
+ // package is uninstalled because overrides cannot be reset if the package is not present.
device.executeShellCommand("am compat reset-all " + CORRUPT_APK_PACKAGE_NAME);
+ device.uninstallPackage(CORRUPT_APK_PACKAGE_NAME);
}
@Before
@@ -132,7 +134,7 @@
private String install(String apk) throws DeviceNotAvailableException, FileNotFoundException {
return getDevice().installPackage(
new CompatibilityBuildHelper(mBuildInfo).getTestFile(apk),
- false /*reinstall*/);
+ true /* reinstall */);
}
/**
@@ -167,12 +169,13 @@
assertInstallDoesNotCrashSystem("CtsCorruptApkTests_b79488511.apk");
}
- /** APKs that target pre-Q and have a compressed resources.arsc can be installed. */
+ /** APKs that target pre-R and have a compressed resources.arsc can be installed. */
public void testFailInstallCompressedARSC_Q() throws Exception {
assertNull(install(COMPRESSED_ARSC_Q));
}
public void testFailInstallCompressedARSC_Q_PlatformConfig_enabled() throws Exception {
+ assertNull(install(COMPRESSED_ARSC_Q));
getDevice().executeShellCommand(String.format("am compat enable %s %s",
FAIL_COMPRESSED_ARSC_PLATFORM_CONFIG_ID, CORRUPT_APK_PACKAGE_NAME));
assertNotNull(install(COMPRESSED_ARSC_Q));
@@ -183,18 +186,13 @@
assertNotNull(install(COMPRESSED_ARSC_R));
}
- public void testFailInstallCompressedARSC_R_PlatformConfig_disabled() throws Exception {
- getDevice().executeShellCommand(String.format("am compat disable %s %s",
- FAIL_COMPRESSED_ARSC_PLATFORM_CONFIG_ID, CORRUPT_APK_PACKAGE_NAME));
- assertNull(install(COMPRESSED_ARSC_R));
- }
-
- /** APKs that target pre-Q and have a unaligned resources.arsc can be installed. */
+ /** APKs that target pre-R and have a unaligned resources.arsc can be installed. */
public void testFailInstallUnalignedARSC_Q() throws Exception {
assertNull(install(UNALIGNED_ARSC_Q));
}
public void testFailInstallUnalignedARSC_Q_PlatformConfig_enabled() throws Exception {
+ assertNull(install(UNALIGNED_ARSC_Q));
getDevice().executeShellCommand(String.format("am compat enable %s %s",
FAIL_COMPRESSED_ARSC_PLATFORM_CONFIG_ID, CORRUPT_APK_PACKAGE_NAME));
assertNotNull(install(UNALIGNED_ARSC_Q));
@@ -204,10 +202,4 @@
public void testFailInstallUnalignedARSC_R() throws Exception {
assertNotNull(install(UNALIGNED_ARSC_R));
}
-
- public void testFailInstallUnalignedARSC_R_PlatformConfig_disabled() throws Exception {
- getDevice().executeShellCommand(String.format("am compat disable %s %s",
- FAIL_COMPRESSED_ARSC_PLATFORM_CONFIG_ID, CORRUPT_APK_PACKAGE_NAME));
- assertNull(install(UNALIGNED_ARSC_R));
- }
}
\ No newline at end of file
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/Android.bp b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/Android.bp
index 915d9a9..0994422 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/Android.bp
@@ -32,4 +32,28 @@
"vts10",
"general-tests",
]
+}
+
+android_test_import {
+ name: "CtsCorruptApkTests_Unaligned_Q",
+ apk: "unaligned_Q.apk",
+ presigned: true,
+ preprocessed: true,
+ test_suites: [
+ "cts",
+ "vts10",
+ "general-tests",
+ ]
+}
+
+android_test_import {
+ name: "CtsCorruptApkTests_Unaligned_R",
+ apk: "unaligned_R.apk",
+ presigned: true,
+ preprocessed: true,
+ test_suites: [
+ "cts",
+ "vts10",
+ "general-tests",
+ ]
}
\ No newline at end of file
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/Android.mk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/Android.mk
deleted file mode 100644
index ae419b6..0000000
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright (C) 2020 Google Inc.
-#
-# 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.
-#
-
-LOCAL_PATH := $(my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CtsCorruptApkTests_Unaligned_Q
-LOCAL_SRC_FILES := unaligned_Q.apk
-LOCAL_MODULE_CLASS := APPS
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_SUFFIX := .apk
-LOCAL_CERTIFICATE := PRESIGNED
-LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/unaligned_Q.apk
-LOCAL_COMPATIBILITY_SUITE := cts vts10 general-tests
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := CtsCorruptApkTests_Unaligned_R
-LOCAL_SRC_FILES := unaligned_R.apk
-LOCAL_MODULE_CLASS := APPS
-LOCAL_MODULE_TAGS := tests
-LOCAL_MODULE_SUFFIX := .apk
-LOCAL_CERTIFICATE := PRESIGNED
-LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/unaligned_R.apk
-LOCAL_COMPATIBILITY_SUITE := cts vts10 general-tests
-include $(BUILD_PREBUILT)
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/AndroidManifest.xml
index b574029..93a223d 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/AndroidManifest.xml
@@ -17,5 +17,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.content.cts.corruptapk" >
- <application android:hasCode="false" />
+ <application android:hasCode="false"
+ android:debuggable="true"/>
</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_Q.apk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_Q.apk
index 58c30cd..afaac5d 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_Q.apk
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_Q.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_R.apk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_R.apk
index 1bdd2bb..ecb009f 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_R.apk
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/compressed_R.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_Q.apk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_Q.apk
index b6023bc..a17200b 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_Q.apk
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_Q.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_R.apk b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_R.apk
index e64bcfd..7296b84 100644
--- a/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_R.apk
+++ b/hostsidetests/appsecurity/test-apps/CorruptApkTests/compressed_arsc/unaligned_R.apk
Binary files differ
diff --git a/hostsidetests/devicepolicy/AndroidTest.xml b/hostsidetests/devicepolicy/AndroidTest.xml
index 575dc04..b579e97 100644
--- a/hostsidetests/devicepolicy/AndroidTest.xml
+++ b/hostsidetests/devicepolicy/AndroidTest.xml
@@ -23,6 +23,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<!-- Device admin/owner requires being run in system user -->
<option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
<!-- Push the list of public APIs to device -->
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
diff --git a/hostsidetests/graphics/gpuprofiling/AndroidTest.xml b/hostsidetests/graphics/gpuprofiling/AndroidTest.xml
index 6dd7410..bfaa33e 100644
--- a/hostsidetests/graphics/gpuprofiling/AndroidTest.xml
+++ b/hostsidetests/graphics/gpuprofiling/AndroidTest.xml
@@ -20,9 +20,13 @@
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsGraphicsProfilingDataApp.apk" />
+ </target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="ctsgraphicsgpuprofilinginit->/data/local/tmp/ctsgraphicsgpuprofilinginit" />
+ <option name="push" value="ctsgraphicsgpucountersinit->/data/local/tmp/ctsgraphicsgpucountersinit" />
<option name="append-bitness" value="true" />
</target_preparer>
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
diff --git a/hostsidetests/graphics/gpuprofiling/app/Android.bp b/hostsidetests/graphics/gpuprofiling/app/Android.bp
index 6c05ece..9bb6ce7 100644
--- a/hostsidetests/graphics/gpuprofiling/app/Android.bp
+++ b/hostsidetests/graphics/gpuprofiling/app/Android.bp
@@ -13,11 +13,11 @@
// limitations under the License.
cc_test {
- name: "ctsgraphicsgpuprofilinginit",
+ name: "ctsgraphicsgpucountersinit",
srcs: [
- "android_graphics_cts_GpuProfilingData.cpp",
+ "android_graphics_cts_GpuCounters.cpp",
],
- test_suites: ["cts"],
+ test_suites: ["cts", "general-tests"],
compile_multilib: "both",
multilib: {
lib32: {
@@ -34,9 +34,44 @@
shared_libs: [
"libdl",
"libandroid",
- "libvulkan",
"liblog",
],
stl: "c++_static",
sdk_version: "current",
}
+
+cc_test_library {
+ name: "libctsgraphicsgpuprofiling_jni",
+ gtest: false,
+ srcs: [
+ "jni/CtsGraphicsProfilingDataJniOnLoad.cpp",
+ "jni/android_graphics_cts_GpuRenderStages.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ header_libs: ["jni_headers"],
+ shared_libs: [
+ "libandroid",
+ "libvulkan",
+ "liblog",
+ ],
+ stl: "c++_shared",
+ sdk_version: "current",
+}
+
+android_test_helper_app {
+ name: "CtsGraphicsProfilingDataApp",
+ defaults: ["cts_support_defaults"],
+ srcs: ["src/**/*.java"],
+ sdk_version: "current",
+ // tag this module as a cts test artifact
+ test_suites: ["cts", "general-tests"],
+ compile_multilib: "both",
+ jni_libs: [
+ "libctsgraphicsgpuprofiling_jni",
+ ],
+ use_embedded_native_libs: false,
+ stl: "c++_shared",
+}
\ No newline at end of file
diff --git a/hostsidetests/graphics/gpuprofiling/app/AndroidManifest.xml b/hostsidetests/graphics/gpuprofiling/app/AndroidManifest.xml
new file mode 100644
index 0000000..da58bef
--- /dev/null
+++ b/hostsidetests/graphics/gpuprofiling/app/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+# Copyright (C) 2020 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.graphics.gpuprofiling.app">
+ <application android:extractNativeLibs="true" android:debuggable="true">
+ <activity android:name=".GpuRenderStagesDeviceActivity" android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/hostsidetests/graphics/gpuprofiling/app/android_graphics_cts_GpuCounters.cpp b/hostsidetests/graphics/gpuprofiling/app/android_graphics_cts_GpuCounters.cpp
new file mode 100644
index 0000000..c710d4f
--- /dev/null
+++ b/hostsidetests/graphics/gpuprofiling/app/android_graphics_cts_GpuCounters.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2020 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.
+ *
+ */
+
+#define LOG_TAG "GpuProfilingData"
+
+#include <chrono>
+#include <csignal>
+#include <string>
+#include <thread>
+#include <unistd.h>
+#include <vector>
+
+#include <android/log.h>
+#include <dlfcn.h>
+
+#define ALOGI(msg, ...) \
+ __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
+#define ALOGE(msg, ...) \
+ __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, (msg), __VA_ARGS__)
+#define ALOGD(msg, ...) \
+ __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, (msg), __VA_ARGS__)
+#define REQUIRE_SUCCESS(fn, name) \
+ do { \
+ if (VK_SUCCESS != fn) { \
+ ALOGE("Vulkan Error in %s", name); \
+ return -1; \
+ } \
+ } while (0)
+
+namespace {
+
+typedef void (*FN_PTR)(void);
+
+/**
+ * Load the vendor provided counter producer library.
+ * startCounterProducer is a thin rewrite of the same producer loading logic in
+ * github.com/google/agi
+ */
+
+int startCounterProducer() {
+ ALOGI("%s", "Loading producer library");
+ char *error;
+ std::string libDir = sizeof(void *) == 8 ? "lib64" : "lib";
+ std::string producerPath = "/vendor/" + libDir + "/libgpudataproducer.so";
+
+ ALOGI("Trying %s", producerPath.c_str());
+ void *handle = dlopen(producerPath.c_str(), RTLD_GLOBAL);
+ if ((error = dlerror()) != nullptr || handle == nullptr) {
+ ALOGE("Error loading lib: %s", error);
+ return -1;
+ }
+
+ FN_PTR startFunc = (FN_PTR)dlsym(handle, "start");
+ if ((error = dlerror()) != nullptr) {
+ ALOGE("Error looking for start symbol: %s", error);
+ dlclose(handle);
+ return -1;
+ }
+
+ if (startFunc == nullptr) {
+ ALOGE("Did not find the producer library %s", producerPath.c_str());
+ ALOGE("LD_LIBRARY_PATH=%s", getenv("LD_LIBRARY_PATH"));
+ return -1;
+ }
+
+ ALOGI("Calling start at %p", startFunc);
+ (*startFunc)();
+ ALOGI("Producer %s has exited.", producerPath.c_str());
+ dlclose(handle);
+ return 0;
+}
+
+volatile std::sig_atomic_t done = 0;
+
+} // anonymous namespace
+
+int main() {
+ std::signal(SIGTERM, [](int /*signal*/) {
+ ALOGI("%s", "SIGTERM received");
+ done = 1;
+ });
+ std::thread dummy([&]() {
+ int result = startCounterProducer();
+ ALOGI("%s %d", "startCounterProducer returned", result);
+ });
+ ALOGI("%s", "Waiting for host");
+ while (!done) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+ return 0;
+}
diff --git a/hostsidetests/graphics/gpuprofiling/app/jni/CtsGraphicsProfilingDataJniOnLoad.cpp b/hostsidetests/graphics/gpuprofiling/app/jni/CtsGraphicsProfilingDataJniOnLoad.cpp
new file mode 100644
index 0000000..5948ff8
--- /dev/null
+++ b/hostsidetests/graphics/gpuprofiling/app/jni/CtsGraphicsProfilingDataJniOnLoad.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 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 <jni.h>
+#include <stdio.h>
+
+extern int register_android_gputools_cts_GpuProfilingData(JNIEnv *);
+
+jint JNI_OnLoad(JavaVM *vm, void * /*reserved*/) {
+ JNIEnv *env = nullptr;
+ if (vm->GetEnv((void **)&env, JNI_VERSION_1_4) != JNI_OK)
+ return JNI_ERR;
+ if (register_android_gputools_cts_GpuProfilingData(env))
+ return JNI_ERR;
+ return JNI_VERSION_1_4;
+}
\ No newline at end of file
diff --git a/hostsidetests/graphics/gpuprofiling/app/android_graphics_cts_GpuProfilingData.cpp b/hostsidetests/graphics/gpuprofiling/app/jni/android_graphics_cts_GpuRenderStages.cpp
similarity index 70%
rename from hostsidetests/graphics/gpuprofiling/app/android_graphics_cts_GpuProfilingData.cpp
rename to hostsidetests/graphics/gpuprofiling/app/jni/android_graphics_cts_GpuRenderStages.cpp
index 19439c0..e0d49c0 100644
--- a/hostsidetests/graphics/gpuprofiling/app/android_graphics_cts_GpuProfilingData.cpp
+++ b/hostsidetests/graphics/gpuprofiling/app/jni/android_graphics_cts_GpuRenderStages.cpp
@@ -17,15 +17,12 @@
#define LOG_TAG "GpuProfilingData"
-#include <chrono>
-#include <csignal>
-#include <string>
-#include <thread>
-#include <unistd.h>
#include <vector>
#include <android/log.h>
#include <dlfcn.h>
+#include <jni.h>
+#include <string>
#include <vulkan/vulkan.h>
#define ALOGI(msg, ...) \
@@ -46,48 +43,7 @@
typedef void (*FN_PTR)(void);
-/**
- * Load the vendor provided counter producer library.
- * startCounterProducer is a thin rewrite of the same producer loading logic in
- * github.com/google/agi
- */
-
-int startCounterProducer() {
- ALOGI("%s", "Loading producer library");
- char *error;
- std::string libDir = sizeof(void *) == 8 ? "lib64" : "lib";
- std::string producerPath = "/vendor/" + libDir + "/libgpudataproducer.so";
-
- ALOGI("Trying %s", producerPath.c_str());
- void *handle = dlopen(producerPath.c_str(), RTLD_GLOBAL);
- if ((error = dlerror()) != nullptr || handle == nullptr) {
- ALOGE("Error loading lib: %s", error);
- return -1;
- }
-
- FN_PTR startFunc = (FN_PTR)dlsym(handle, "start");
- if ((error = dlerror()) != nullptr) {
- ALOGE("Error looking for start symbol: %s", error);
- dlclose(handle);
- return -1;
- }
-
- if (startFunc == nullptr) {
- ALOGE("Did not find the producer library %s", producerPath.c_str());
- ALOGE("LD_LIBRARY_PATH=%s", getenv("LD_LIBRARY_PATH"));
- return -1;
- }
-
- ALOGI("Calling start at %p", startFunc);
- (*startFunc)();
- ALOGI("Producer %s has exited.", producerPath.c_str());
- dlclose(handle);
- return 0;
-}
-
-int initVulkan(VkDevice &device) {
- std::string result = "";
-
+int initVulkan() {
const VkApplicationInfo appInfo = {
VK_STRUCTURE_TYPE_APPLICATION_INFO,
nullptr, // pNext
@@ -171,34 +127,27 @@
nullptr,
};
+ VkDevice device;
+
REQUIRE_SUCCESS(
vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device),
"vkCreateDevice");
-
return 0;
}
-volatile std::sig_atomic_t done = 0;
+jint android_graphics_cts_GpuProfilingData_nativeInitVulkan(JNIEnv * /*env*/,
+ jclass /*clazz*/) {
+ return (jint)initVulkan();
+}
+static JNINativeMethod gMethods[] = {
+ {"nativeInitVulkan", "()I",
+ (void *)android_graphics_cts_GpuProfilingData_nativeInitVulkan}};
} // anonymous namespace
-int main() {
- ALOGI("%s", "Creating Vulkan device");
- VkDevice device;
- std::signal(SIGTERM, [](int /*signal*/) {
- ALOGI("%s", "SIGTERM received");
- done = 1;
- });
- int result = initVulkan(device);
- ALOGI("%s %d", "initVulkan returned", result);
- std::thread dummy([&]() {
- result = startCounterProducer();
- ALOGI("%s %d", "startCounterProducer returned", result);
- });
- ALOGI("%s", "Waiting for host");
- while (!done) {
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
- }
- vkDestroyDevice(device, nullptr);
- return 0;
-}
+int register_android_gputools_cts_GpuProfilingData(JNIEnv *env) {
+ jclass clazz = env->FindClass(
+ "android/graphics/gpuprofiling/app/GpuRenderStagesDeviceActivity");
+ return env->RegisterNatives(clazz, gMethods,
+ sizeof(gMethods) / sizeof(JNINativeMethod));
+}
\ No newline at end of file
diff --git a/hostsidetests/graphics/gpuprofiling/app/src/android/gpuprofiling/GpuRenderStagesDeviceActivity.java b/hostsidetests/graphics/gpuprofiling/app/src/android/gpuprofiling/GpuRenderStagesDeviceActivity.java
new file mode 100644
index 0000000..e6bd660
--- /dev/null
+++ b/hostsidetests/graphics/gpuprofiling/app/src/android/gpuprofiling/GpuRenderStagesDeviceActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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.graphics.gpuprofiling.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+public class GpuRenderStagesDeviceActivity extends Activity {
+
+ static {
+ System.loadLibrary("ctsgraphicsgpuprofiling_jni");
+ }
+
+ private static final String TAG = GpuRenderStagesDeviceActivity.class.getSimpleName();
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ int result = nativeInitVulkan();
+ Log.i(TAG, "nativeInitVulkan returned: " + result);
+ Log.i(TAG, "GpuProfilingData activity complete");
+ }
+
+ private static native int nativeInitVulkan();
+}
diff --git a/hostsidetests/graphics/gpuprofiling/src/android/graphics/gpuprofiling/cts/CtsGpuProfilingDataTest.java b/hostsidetests/graphics/gpuprofiling/src/android/graphics/gpuprofiling/cts/CtsGpuProfilingDataTest.java
index ff33375..f5654cd 100644
--- a/hostsidetests/graphics/gpuprofiling/src/android/graphics/gpuprofiling/cts/CtsGpuProfilingDataTest.java
+++ b/hostsidetests/graphics/gpuprofiling/src/android/graphics/gpuprofiling/cts/CtsGpuProfilingDataTest.java
@@ -17,6 +17,7 @@
package android.graphics.gpuprofiling.cts;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.util.CommandResult;
@@ -46,11 +47,16 @@
// Positive tests
// - Ensure the perfetto producers for render stages, counters, and ftrace gpu frequency are available
- private static final String BIN_NAME = "ctsgraphicsgpuprofilinginit";
+ private static final String BIN_NAME = "ctsgraphicsgpucountersinit";
private static final String DEVICE_BIN_PATH = "/data/local/tmp/" + BIN_NAME;
+ private static final String APP = "android.graphics.gpuprofiling.app";
+ private static final String APK = "CtsGraphicsProfilingDataApp.apk";
+ private static final String ACTIVITY = "GpuRenderStagesDeviceActivity";
private static final String COUNTERS_SOURCE_NAME = "gpu.counters";
private static final String STAGES_SOURCE_NAME = "gpu.renderstages";
- private static final String PROFILING_PROPERTY = "ro.hardware.gpu.profiler.support";
+ private static final String PROFILING_PROPERTY = "graphics.gpu.profiler.support";
+ private static final String LAYER_PACKAGE_PROPERTY = "graphics.gpu.profiler.vulkan_layer_apk";
+ private static final String LAYER_NAME = "VkRenderStagesProducer";
private static int MAX_RETRIES = 5;
private class ShellThread extends Thread {
@@ -65,28 +71,40 @@
@Override
public void run() {
try {
- CommandResult activityStatus = getDevice().executeShellV2Command(mCmd);
+ getDevice().executeShellV2Command(mCmd);
} catch (Exception e) {
- // TODO Do something here?
+ CLog.e("Failed to start counters producer" + e.getMessage());
}
}
}
/**
- * Kill the native process after each test
+ * Kill the native process and remove the layer related settings after each test
*/
@After
public void cleanup() throws Exception {
- // TODO figure out how to unregister the producers
getDevice().executeShellV2Command("killall " + BIN_NAME);
+ getDevice().executeShellV2Command("am force-stop " + APP);
+ getDevice().executeShellV2Command("settings delete global gpu_debug_layers");
+ getDevice().executeShellV2Command("settings delete global enable_gpu_debug_layers");
+ getDevice().executeShellV2Command("settings delete global gpu_debug_app");
+ getDevice().executeShellV2Command("settings delete global gpu_debug_layer_app");
}
/**
- * Clean up before starting any tests.
+ * Clean up before starting any tests. Apply the necessary layer settings if we need them
*/
@Before
public void init() throws Exception {
cleanup();
+ String layerApp = getDevice().getProperty(LAYER_PACKAGE_PROPERTY);
+ if (layerApp != null && !layerApp.isEmpty()) {
+ getDevice().executeShellV2Command("settings put global enable_gpu_debug_layers 1");
+ getDevice().executeShellV2Command("settings put global gpu_debug_app " + APP);
+ getDevice().executeShellV2Command("settings put global gpu_debug_layer_app " + layerApp);
+ getDevice().executeShellV2Command("settings put global gpu_debug_layers " + LAYER_NAME);
+ }
+ installPackage(APK);
}
/**
@@ -100,6 +118,7 @@
// Spin up a new thread to avoid blocking the main thread while the native process waits to be killed.
ShellThread shellThread = new ShellThread(DEVICE_BIN_PATH);
shellThread.start();
+ CommandResult activityStatus = getDevice().executeShellV2Command("am start -n " + APP + "/." + ACTIVITY);
boolean countersSourceFound = false;
boolean stagesSourceFound = false;
for(int i = 0; i < MAX_RETRIES; i++) {
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeHostTest.java
index 33e3e94..dbfa9fb 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeHostTest.java
@@ -33,7 +33,8 @@
private void setupNewPublicVolume() throws Exception {
if (!mIsPublicVolumeSetup) {
- runDeviceTest("setupNewPublicVolume");
+ assertTrue(runDeviceTests("android.scopedstorage.cts",
+ "android.scopedstorage.cts.PublicVolumeTestHelper", "setupNewPublicVolume"));
mIsPublicVolumeSetup = true;
}
}
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeLegacyHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeLegacyHostTest.java
index 8ed0101..c9bd65f 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeLegacyHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/PublicVolumeLegacyHostTest.java
@@ -33,7 +33,8 @@
private void setupNewPublicVolume() throws Exception {
if (!mIsPublicVolumeSetup) {
- runDeviceTest("setupNewPublicVolume");
+ assertTrue(runDeviceTests("android.scopedstorage.cts",
+ "android.scopedstorage.cts.PublicVolumeTestHelper", "setupNewPublicVolume"));
mIsPublicVolumeSetup = true;
}
}
diff --git a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
index 108b3e8..88be97c 100644
--- a/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
+++ b/hostsidetests/scopedstorage/host/src/android/scopedstorage/cts/host/ScopedStorageHostTest.java
@@ -166,6 +166,7 @@
runDeviceTest("testCreateUpperCaseDeleteLowerCase");
runDeviceTest("testCreateMixedCaseDeleteDifferentMixedCase");
runDeviceTest("testAndroidDataObbDoesNotForgetMount");
+ runDeviceTest("testCacheConsistencyForCaseInsensitivity");
}
@Test
diff --git a/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/PublicVolumeLegacyTest.java b/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/PublicVolumeLegacyTest.java
index 57ddf29..7e59505 100644
--- a/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/PublicVolumeLegacyTest.java
+++ b/hostsidetests/scopedstorage/legacy/src/android/scopedstorage/cts/legacy/PublicVolumeLegacyTest.java
@@ -23,7 +23,6 @@
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
-import org.junit.Test;
import org.junit.runner.RunWith;
/**
@@ -39,13 +38,4 @@
TestUtils.setExternalStorageVolume(volumeName);
super.setup();
}
-
- /**
- * This is not an actual test, but rather just a one time setup method that creates the new
- * public volume on which the test would run.
- */
- @Test
- public void setupNewPublicVolume() throws Exception {
- TestUtils.createNewPublicVolume();
- }
}
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/PublicVolumeTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/PublicVolumeTest.java
index b0bf57e..e1fed5d 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/PublicVolumeTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/PublicVolumeTest.java
@@ -23,7 +23,6 @@
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
-import org.junit.Test;
import org.junit.runner.RunWith;
/**
@@ -39,13 +38,4 @@
TestUtils.setExternalStorageVolume(volumeName);
super.setup();
}
-
- /**
- * This is not an actual test, but rather just a one time setup method that creates the new
- * public volume on which the test would run.
- */
- @Test
- public void setupNewPublicVolume() throws Exception {
- TestUtils.createNewPublicVolume();
- }
}
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/PublicVolumeTestHelper.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/PublicVolumeTestHelper.java
new file mode 100644
index 0000000..ce5d2a2
--- /dev/null
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/PublicVolumeTestHelper.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.scopedstorage.cts;
+
+import android.scopedstorage.cts.lib.TestUtils;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Creates public volume for running tests from {@link PublicVolumeTest} and
+ * {@link PublicVolumeLegacyTest}
+ */
+@RunWith(AndroidJUnit4.class)
+public class PublicVolumeTestHelper {
+ /**
+ * This is not an actual test, but rather just a one time setup method that creates the new
+ * public volume on which the test would run.
+ */
+ @Test
+ public void setupNewPublicVolume() throws Exception {
+ TestUtils.createNewPublicVolume();
+ }
+}
diff --git a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
index d3b109b..1842d1c 100644
--- a/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
+++ b/hostsidetests/scopedstorage/src/android/scopedstorage/cts/ScopedStorageTest.java
@@ -867,14 +867,14 @@
try {
assertThat(file.createNewFile()).isTrue();
- // Since we can only place one F_WRLCK, the second open for readPfd will go
- // throuh FUSE
+ // We upgrade 'w' only to 'rw'
ParcelFileDescriptor writePfd = openWithMediaProvider(file, "w");
ParcelFileDescriptor readPfd = openWithMediaProvider(file, "rw");
assertRWR(readPfd, writePfd);
+ assertRWR(writePfd, readPfd); // Can read on 'w' only pfd
assertLowerFsFd(writePfd);
- assertUpperFsFd(readPfd); // Without cache
+ assertLowerFsFd(readPfd);
} finally {
file.delete();
}
@@ -1030,6 +1030,27 @@
assertThat(beforeObbStruct.st_dev).isEqualTo(afterObbStruct.st_dev);
}
+ @Test
+ public void testCacheConsistencyForCaseInsensitivity() throws Exception {
+ File upperCaseFile = new File(getDownloadDir(), "CACHE_CONSISTENCY_FOR_CASE_INSENSITIVITY");
+ File lowerCaseFile = new File(getDownloadDir(), "cache_consistency_for_case_insensitivity");
+
+ try {
+ ParcelFileDescriptor upperCasePfd =
+ ParcelFileDescriptor.open(upperCaseFile,
+ ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_CREATE);
+ ParcelFileDescriptor lowerCasePfd =
+ ParcelFileDescriptor.open(lowerCaseFile,
+ ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE_CREATE);
+
+ assertRWR(upperCasePfd, lowerCasePfd);
+ assertRWR(lowerCasePfd, upperCasePfd);
+ } finally {
+ upperCaseFile.delete();
+ lowerCaseFile.delete();
+ }
+ }
+
private void createDeleteCreate(File create, File delete) throws Exception {
try {
assertThat(create.createNewFile()).isTrue();
@@ -1042,7 +1063,7 @@
Thread.sleep(5);
} finally {
create.delete();
- create.delete();
+ delete.delete();
}
}
@@ -1979,6 +2000,8 @@
final File downloadDir = getDownloadDir();
final File otherAppPdf = new File(downloadDir, "other-" + NONMEDIA_FILE_NAME);
+ final File shellPdfAtRoot = new File(getExternalStorageDir(),
+ "shell-" + NONMEDIA_FILE_NAME);
final File otherAppImage = new File(getDcimDir(), "other-" + IMAGE_FILE_NAME);
final File myAppPdf = new File(downloadDir, "my-" + NONMEDIA_FILE_NAME);
final File doesntExistPdf = new File(downloadDir, "nada-" + NONMEDIA_FILE_NAME);
@@ -1993,14 +2016,21 @@
assertThat(myAppPdf.createNewFile()).isTrue();
assertFileAccess_readWrite(myAppPdf);
- // We can read the other app's image file because we hold R_E_S, but we can only
- // check exists for the pdf file.
+ // We can read the other app's image file because we hold R_E_S, but we can
+ // check only exists for the pdf files.
assertFileAccess_readOnly(otherAppImage);
assertFileAccess_existsOnly(otherAppPdf);
assertAccess(doesntExistPdf, false, false, false);
+
+ // We can check only exists for another app's files on root.
+ // Use shell to create root file because TEST_APP_A is in
+ // scoped storage.
+ executeShellCommand("touch " + shellPdfAtRoot.getAbsolutePath());
+ assertFileAccess_existsOnly(shellPdfAtRoot);
} finally {
deleteFileAsNoThrow(TEST_APP_A, otherAppPdf.getAbsolutePath());
deleteFileAsNoThrow(TEST_APP_A, otherAppImage.getAbsolutePath());
+ executeShellCommand("rm " + shellPdfAtRoot.getAbsolutePath());
myAppPdf.delete();
uninstallApp(TEST_APP_A);
}
@@ -2024,17 +2054,17 @@
// We cannot read or write the file, but app A can.
assertThat(canReadAndWriteAs(TEST_APP_A,
otherAppExternalDataFile.getAbsolutePath())).isTrue();
- assertCannotAccessOtherAppFile(otherAppExternalDataFile);
+ assertCannotReadOrWrite(otherAppExternalDataFile);
// We cannot read or write the dir, but app A can.
assertThat(canReadAndWriteAs(TEST_APP_A,
otherAppExternalDataDir.getAbsolutePath())).isTrue();
- assertCannotAccessOtherAppFile(otherAppExternalDataDir);
+ assertCannotReadOrWrite(otherAppExternalDataDir);
// We cannot read or write the sub dir, but app A can.
assertThat(canReadAndWriteAs(TEST_APP_A,
otherAppExternalDataSubDir.getAbsolutePath())).isTrue();
- assertCannotAccessOtherAppFile(otherAppExternalDataSubDir);
+ assertCannotReadOrWrite(otherAppExternalDataSubDir);
// We can read and write our own app dir, but app A cannot.
assertThat(canReadAndWriteAs(TEST_APP_A,
@@ -2045,6 +2075,7 @@
assertDirectoryAccess(getExternalStorageDir(), true);
assertDirectoryAccess(new File(getExternalStorageDir(), "Android"), true);
assertDirectoryAccess(new File(getExternalStorageDir(), "doesnt/exist"), false);
+ assertCannotReadOrWrite(new File("/storage/emulated"));
} finally {
uninstallApp(TEST_APP_A); // Uninstalling deletes external app dirs
}
@@ -2747,7 +2778,7 @@
assertAccess(file, exists, canRead, canWrite, true /* checkExists */);
}
- private static void assertCannotAccessOtherAppFile(File file)
+ private static void assertCannotReadOrWrite(File file)
throws Exception {
// App data directories have different 'x' bits on upgrading vs new devices. Let's not
// check 'exists', by passing checkExists=false. But assert this app cannot read or write
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index 6b7dd04..de90629 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -1258,10 +1258,11 @@
assertDomainZeroOrOne("u:r:wpa:s0", "/system/bin/wpa_supplicant");
}
- /* permissioncontroller may or may not be running */
+ /* permissioncontroller, if running, always runs in permissioncontroller_app */
@CddTest(requirement="9.7")
public void testPermissionControllerDomain() throws DeviceNotAvailableException {
- assertDomainZeroOrOne("u:r:permissioncontroller_app:s0", "com.google.android.permissioncontroller");
+ assertExecutableHasDomain("com.google.android.permissioncontroller", "u:r:permissioncontroller_app:s0");
+ assertExecutableHasDomain("com.android.permissioncontroller", "u:r:permissioncontroller_app:s0");
}
/* vzwomatrigger may or may not be running */
diff --git a/hostsidetests/statsd/apps/statsdapp/Android.bp b/hostsidetests/statsd/apps/statsdapp/Android.bp
index eabea94..a76c07e 100644
--- a/hostsidetests/statsd/apps/statsdapp/Android.bp
+++ b/hostsidetests/statsd/apps/statsdapp/Android.bp
@@ -45,6 +45,7 @@
"androidx.legacy_legacy-support-v4",
"androidx.test.rules",
"cts-net-utils",
+ "BlobStoreTestUtils"
],
jni_libs: ["liblmkhelper"],
compile_multilib: "both",
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
index 72bea3d..9311656 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/AtomTests.java
@@ -27,6 +27,7 @@
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
+import android.app.blob.BlobStoreManager;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.bluetooth.BluetoothAdapter;
@@ -61,6 +62,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
+import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
import android.os.SystemClock;
@@ -75,6 +77,11 @@
import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.utils.blob.DummyBlobData;
+
+import com.google.common.io.BaseEncoding;
+
import org.junit.Test;
import java.net.HttpURLConnection;
@@ -82,6 +89,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
@@ -677,7 +685,7 @@
long startTime = System.currentTimeMillis();
CountDownLatch latch = StatsdJobService.resetCountDownLatch();
js.schedule(job);
- waitForReceiver(context, 2_500, latch, null);
+ waitForReceiver(context, 5_000, latch, null);
}
@Test
@@ -938,6 +946,42 @@
context.stopService(intent);
}
+
+ // Constants for testBlobStore
+ private static final long BLOB_COMMIT_CALLBACK_TIMEOUT_SEC = 5;
+ private static final long BLOB_EXPIRY_DURATION_MS = 24 * 60 * 60 * 1000;
+ private static final long BLOB_FILE_SIZE_BYTES = 23 * 1024L;
+ private static final long BLOB_LEASE_EXPIRY_DURATION_MS = 60 * 60 * 1000;
+ private static final byte[] FAKE_PKG_CERT_SHA256 = BaseEncoding.base16().decode(
+ "187E3D3172F2177D6FEC2EA53785BF1E25DFF7B2E5F6E59807E365A7A837E6C3");
+
+ @Test
+ public void testBlobStore() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ int uid = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).uid;
+
+ BlobStoreManager bsm = context.getSystemService(BlobStoreManager.class);
+ final long leaseExpiryMs = System.currentTimeMillis() + BLOB_LEASE_EXPIRY_DURATION_MS;
+
+ final DummyBlobData blobData = new DummyBlobData.Builder(context).setExpiryDurationMs(
+ BLOB_EXPIRY_DURATION_MS).setFileSize(BLOB_FILE_SIZE_BYTES).build();
+
+ blobData.prepare();
+ try {
+ // Commit the Blob, should result in BLOB_COMMITTED atom event
+ commitBlob(context, bsm, blobData);
+
+ // Lease the Blob, should result in BLOB_LEASED atom event
+ bsm.acquireLease(blobData.getBlobHandle(), "", leaseExpiryMs);
+
+ // Open the Blob, should result in BLOB_OPENED atom event
+ bsm.openBlob(blobData.getBlobHandle());
+
+ } finally {
+ blobData.delete();
+ }
+ }
+
// ------- Helper methods
/** Puts the current thread to sleep. */
@@ -994,4 +1038,19 @@
private static void setScreenBrightness(int brightness) {
runShellCommand("settings put system screen_brightness " + brightness);
}
+
+
+ private void commitBlob(Context context, BlobStoreManager bsm, DummyBlobData blobData)
+ throws Exception {;
+ final long sessionId = bsm.createSession(blobData.getBlobHandle());
+ try (BlobStoreManager.Session session = bsm.openSession(sessionId)) {
+ blobData.writeToSession(session);
+ session.allowPackageAccess("fake.package.name", FAKE_PKG_CERT_SHA256);
+
+ final CompletableFuture<Integer> callback = new CompletableFuture<>();
+ session.commit(context.getMainExecutor(), callback::complete);
+ assertWithMessage("Session failed to commit within timeout").that(
+ callback.get(BLOB_COMMIT_CALLBACK_TIMEOUT_SEC, TimeUnit.SECONDS)).isEqualTo(0);
+ }
+ }
}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java
index 329bdfa..d81040f 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdJobService.java
@@ -28,6 +28,8 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import javax.annotation.concurrent.GuardedBy;
+
/**
* Handles callback from the framework {@link android.app.job.JobScheduler}.
* Runs a job for 0.5 seconds. Provides a countdown latch to wait on, by the test that schedules it.
@@ -38,6 +40,10 @@
JobInfo mRunningJobInfo;
JobParameters mRunningParams;
+
+ private static final Object sLock = new Object();
+
+ @GuardedBy("sLock")
private static CountDownLatch sLatch;
final Handler mHandler = new Handler();
@@ -47,24 +53,27 @@
Thread.sleep(500);
} catch (InterruptedException e) {
}
+
jobFinished(mRunningParams, false);
- if (sLatch != null) {
- sLatch.countDown();
+
+ synchronized (sLock) {
+ if (sLatch != null) {
+ sLatch.countDown();
+ }
}
}
};
public static synchronized CountDownLatch resetCountDownLatch() {
- sLatch = new CountDownLatch(1);
+ synchronized (sLock) {
+ if (sLatch == null || sLatch.getCount() == 0) {
+ sLatch = new CountDownLatch(1);
+ }
+ }
return sLatch;
}
@Override
- public void onCreate() {
- super.onCreate();
- }
-
- @Override
public boolean onStartJob(JobParameters params) {
mRunningParams = params;
mHandler.post(mWorker);
@@ -75,4 +84,4 @@
public boolean onStopJob(JobParameters params) {
return false;
}
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java
index 12f110b..6968307 100644
--- a/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java
+++ b/hostsidetests/statsd/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdSyncAdapter.java
@@ -58,7 +58,6 @@
}
synchronized (sLock) {
Log.i(TAG, "onPerformSync");
- sLock.notifyAll();
if (sLatch != null) {
sLatch.countDown();
} else {
@@ -79,8 +78,12 @@
ContentResolver.requestSync(account, StatsdProvider.AUTHORITY, extras);
}
- public static synchronized CountDownLatch resetCountDownLatch() {
- sLatch = new CountDownLatch(1);
+ public static CountDownLatch resetCountDownLatch() {
+ synchronized (sLock) {
+ if (sLatch == null || sLatch.getCount() == 0) {
+ sLatch = new CountDownLatch(1);
+ }
+ }
return sLatch;
}
}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
index ef216cc..51e24ea 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/AtomTestCase.java
@@ -205,22 +205,24 @@
private String probe(String path) throws Exception {
return getDevice().executeShellCommand("if [ -e " + path + " ] ; then"
- + " cat " + path + " ; else echo 0 ; fi");
+ + " cat " + path + " ; else echo -1 ; fi");
}
/**
* Determines whether perfetto enabled the kernel ftrace tracer.
*/
protected boolean isSystemTracingEnabled() throws Exception {
- final String debugFsPath = "/sys/kernel/debug/tracing/tracing_on";
final String traceFsPath = "/sys/kernel/tracing/tracing_on";
- String tracing_on = probe(debugFsPath);
+ String tracing_on = probe(traceFsPath);
if (tracing_on.startsWith("0")) return false;
if (tracing_on.startsWith("1")) return true;
- // fallback to traceFs
- LogUtil.CLog.d("Unexpected state for %s = %s. Falling back to traceFs", debugFsPath,
+
+ // fallback to debugfs
+ LogUtil.CLog.d("Unexpected state for %s = %s. Falling back to debugfs", traceFsPath,
tracing_on);
- tracing_on = probe(traceFsPath);
+
+ final String debugFsPath = "/sys/kernel/debug/tracing/tracing_on";
+ tracing_on = probe(debugFsPath);
if (tracing_on.startsWith("0")) return false;
if (tracing_on.startsWith("1")) return true;
throw new Exception(String.format("Unexpected state for %s = %s", traceFsPath, tracing_on));
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
index a54f44e..6668d8f 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/UidAtomTests.java
@@ -16,6 +16,7 @@
package android.cts.statsd.atom;
import static com.android.os.AtomsProto.IntegrityCheckResultReported.Response.ALLOWED;
+
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
@@ -24,6 +25,7 @@
import android.os.WakeLockLevelEnum;
import android.server.ErrorSource;
import android.telephony.NetworkTypeEnum;
+
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.compatibility.common.util.PropertyUtil;
import com.android.internal.os.StatsdConfigProto.StatsdConfig;
@@ -41,6 +43,9 @@
import com.android.os.AtomsProto.BinderCalls;
import com.android.os.AtomsProto.BleScanResultReceived;
import com.android.os.AtomsProto.BleScanStateChanged;
+import com.android.os.AtomsProto.BlobCommitted;
+import com.android.os.AtomsProto.BlobLeased;
+import com.android.os.AtomsProto.BlobOpened;
import com.android.os.AtomsProto.CameraStateChanged;
import com.android.os.AtomsProto.DangerousPermissionState;
import com.android.os.AtomsProto.DangerousPermissionStateSampled;
@@ -77,8 +82,10 @@
import com.android.os.StatsLog.EventMetricData;
import com.android.server.notification.SmallHash;
import com.android.tradefed.log.LogUtil;
+
import com.google.common.collect.Range;
import com.google.protobuf.Descriptors;
+
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@@ -180,11 +187,12 @@
createAndUploadConfig(atomTag, false);
Thread.sleep(WAIT_TIME_SHORT);
- runActivity("StatsdCtsForegroundActivity", "action", "action.sleep_top");
+ runActivity("StatsdCtsForegroundActivity", "action", "action.sleep_top", 3_500);
// Sorted list of events in order in which they occurred.
List<EventMetricData> data = getEventMetricDataList();
+ assertThat(data).hasSize(1);
AppStartOccurred atom = data.get(0).getAtom().getAppStartOccurred();
assertThat(atom.getPkgName()).isEqualTo(TEST_PACKAGE_NAME);
assertThat(atom.getActivityName())
@@ -676,7 +684,7 @@
assertThat(state.getLocationReports()).isGreaterThan((long) 0);
assertThat(state.getLocationFailureReports()).isAtLeast((long) 0);
assertThat(state.getTimeToFirstFixReports()).isGreaterThan((long) 0);
- assertThat(state.getTimeToFirstFixMilliS()).isGreaterThan((long) 0);
+ assertThat(state.getTimeToFirstFixMillis()).isGreaterThan((long) 0);
assertThat(state.getPositionAccuracyReports()).isGreaterThan((long) 0);
assertThat(state.getPositionAccuracyMeters()).isGreaterThan((long) 0);
assertThat(state.getTopFourAverageCn0Reports()).isGreaterThan((long) 0);
@@ -891,8 +899,9 @@
List<EventMetricData> data = getEventMetricDataList();
// Assert that the events happened in the expected order.
- assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT,
- atom -> atom.getSyncStateChanged().getState().getNumber());
+ assertStatesOccurred(stateSet, data,
+ /* wait = */ 0 /* don't verify time differences between state changes */,
+ atom -> atom.getSyncStateChanged().getState().getNumber());
}
public void testVibratorState() throws Exception {
@@ -1308,8 +1317,8 @@
// Start test app and trigger a pull while it is running.
try (AutoCloseable a = withActivity("StatsdCtsForegroundActivity", "action",
"action.show_notification")) {
- setAppBreadcrumbPredicate();
Thread.sleep(WAIT_TIME_LONG);
+ setAppBreadcrumbPredicate();
}
// Assert about ProcessMemorySnapshot for the test app, statsd and system server.
@@ -1999,12 +2008,9 @@
doTestMobileBytesTransferThat(Atom.MOBILE_BYTES_TRANSFER_BY_FG_BG_FIELD_NUMBER, (atom) -> {
final AtomsProto.MobileBytesTransferByFgBg data =
((Atom) atom).getMobileBytesTransferByFgBg();
- if (data.getUid() == appUid) {
+ if (data.getUid() == appUid && data.getIsForeground()) {
assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
data.getRxPackets(), data.getTxPackets());
- // IsForeground cannot be judged since foreground activity that launched
- // while screen off (PROCESS_STATE_TOP_SLEEPING) will be treated as background
- // in NetworkPolicyManagerService.
return true; // found
}
return false;
@@ -2017,25 +2023,27 @@
doTestMobileBytesTransferThat(Atom.DATA_USAGE_BYTES_TRANSFER_FIELD_NUMBER, (atom) -> {
final AtomsProto.DataUsageBytesTransfer data =
((Atom) atom).getDataUsageBytesTransfer();
- assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
- data.getRxPackets(), data.getTxPackets());
- // TODO: verify the RAT type field with the value gotten from device.
- if (subtypeCombined) {
- assertThat(data.getRatType()).isEqualTo(NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
- } else {
- assertThat(data.getRatType()).isGreaterThan(
- NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
+ if (data.getState() == 1 /*NetworkStats.SET_FOREGROUND*/) {
+ assertDataUsageAtomDataExpected(data.getRxBytes(), data.getTxBytes(),
+ data.getRxPackets(), data.getTxPackets());
+ // TODO: verify the RAT type field with the value gotten from device.
+ if (subtypeCombined) {
+ assertThat(data.getRatType()).isEqualTo(
+ NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
+ } else {
+ assertThat(data.getRatType()).isGreaterThan(
+ NetworkTypeEnum.NETWORK_TYPE_UNKNOWN_VALUE);
+ }
+
+ // Assert that subscription info is valid.
+ assertThat(data.getSimMcc()).matches("^\\d{3}$");
+ assertThat(data.getSimMnc()).matches("^\\d{2,3}$");
+ assertThat(data.getCarrierId()).isNotEqualTo(
+ -1); // TelephonyManager#UNKNOWN_CARRIER_ID
+
+ return true; // found
}
- // Foreground state cannot be judged since foreground activity that launched
- // while screen off (PROCESS_STATE_TOP_SLEEPING) will be treated as background
- // in NetworkPolicyManagerService.
-
- // Assert that subscription info is valid.
- assertThat(data.getSimMcc()).matches("^\\d{3}$");
- assertThat(data.getSimMnc()).matches("^\\d{2,3}$");
- assertThat(data.getCarrierId()).isNotEqualTo(-1); // TelephonyManager#UNKNOWN_CARRIER_ID
-
- return true;
+ return false;
});
}
@@ -2071,6 +2079,107 @@
assertThat(atom.getState()).isEqualTo(AppBreadcrumbReported.State.START);
}
+ public void testPushedBlobStoreStats() throws Exception {
+ StatsdConfig.Builder conf = createConfigBuilder();
+ addAtomEvent(conf, Atom.BLOB_COMMITTED_FIELD_NUMBER, false);
+ addAtomEvent(conf, Atom.BLOB_LEASED_FIELD_NUMBER, false);
+ addAtomEvent(conf, Atom.BLOB_OPENED_FIELD_NUMBER, false);
+ uploadConfig(conf);
+
+ Thread.sleep(WAIT_TIME_SHORT);
+
+ runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testBlobStore");
+
+ List<EventMetricData> data = getEventMetricDataList();
+ assertThat(data).hasSize(3);
+
+ BlobCommitted blobCommitted = data.get(0).getAtom().getBlobCommitted();
+ final long blobId = blobCommitted.getBlobId();
+ final long blobSize = blobCommitted.getSize();
+ assertThat(blobCommitted.getUid()).isEqualTo(getUid());
+ assertThat(blobId).isNotEqualTo(0);
+ assertThat(blobSize).isNotEqualTo(0);
+ assertThat(blobCommitted.getResult()).isEqualTo(BlobCommitted.Result.SUCCESS);
+
+ BlobLeased blobLeased = data.get(1).getAtom().getBlobLeased();
+ assertThat(blobLeased.getUid()).isEqualTo(getUid());
+ assertThat(blobLeased.getBlobId()).isEqualTo(blobId);
+ assertThat(blobLeased.getSize()).isEqualTo(blobSize);
+ assertThat(blobLeased.getResult()).isEqualTo(BlobLeased.Result.SUCCESS);
+
+ BlobOpened blobOpened = data.get(2).getAtom().getBlobOpened();
+ assertThat(blobOpened.getUid()).isEqualTo(getUid());
+ assertThat(blobOpened.getBlobId()).isEqualTo(blobId);
+ assertThat(blobOpened.getSize()).isEqualTo(blobSize);
+ assertThat(blobOpened.getResult()).isEqualTo(BlobOpened.Result.SUCCESS);
+ }
+
+ // Constants that match the constants for AtomTests#testBlobStore
+ private static final long BLOB_COMMIT_CALLBACK_TIMEOUT_SEC = 5;
+ private static final long BLOB_EXPIRY_DURATION_MS = 24 * 60 * 60 * 1000;
+ private static final long BLOB_FILE_SIZE_BYTES = 23 * 1024L;
+ private static final long BLOB_LEASE_EXPIRY_DURATION_MS = 60 * 60 * 1000;
+
+ public void testPulledBlobStoreStats() throws Exception {
+ StatsdConfig.Builder config = createConfigBuilder();
+ addGaugeAtomWithDimensions(config,
+ Atom.BLOB_INFO_FIELD_NUMBER,
+ null);
+ uploadConfig(config);
+
+ final long testStartTimeMs = System.currentTimeMillis();
+ Thread.sleep(WAIT_TIME_SHORT);
+ runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", "testBlobStore");
+ Thread.sleep(WAIT_TIME_LONG);
+ setAppBreadcrumbPredicate();
+ Thread.sleep(WAIT_TIME_SHORT);
+
+ // Add commit callback time to test end time to account for async execution
+ final long testEndTimeMs =
+ System.currentTimeMillis() + BLOB_COMMIT_CALLBACK_TIMEOUT_SEC * 1000;
+
+ // Find the BlobInfo for the blob created in the test run
+ AtomsProto.BlobInfo blobInfo = null;
+ for (Atom atom : getGaugeMetricDataList()) {
+ if (atom.hasBlobInfo()) {
+ final AtomsProto.BlobInfo temp = atom.getBlobInfo();
+ if (temp.getCommitters().getCommitter(0).getUid() == getUid()) {
+ blobInfo = temp;
+ break;
+ }
+ }
+ }
+ assertThat(blobInfo).isNotNull();
+
+ assertThat(blobInfo.getSize()).isEqualTo(BLOB_FILE_SIZE_BYTES);
+
+ // Check that expiry time is reasonable
+ assertThat(blobInfo.getExpiryTimestampMillis()).isGreaterThan(
+ testStartTimeMs + BLOB_EXPIRY_DURATION_MS);
+ assertThat(blobInfo.getExpiryTimestampMillis()).isLessThan(
+ testEndTimeMs + BLOB_EXPIRY_DURATION_MS);
+
+ // Check that commit time is reasonable
+ final long commitTimeMs = blobInfo.getCommitters().getCommitter(
+ 0).getCommitTimestampMillis();
+ assertThat(commitTimeMs).isGreaterThan(testStartTimeMs);
+ assertThat(commitTimeMs).isLessThan(testEndTimeMs);
+
+ // Check that WHITELIST and PRIVATE access mode flags are set
+ assertThat(blobInfo.getCommitters().getCommitter(0).getAccessMode()).isEqualTo(0b1001);
+ assertThat(blobInfo.getCommitters().getCommitter(0).getNumWhitelistedPackage()).isEqualTo(
+ 1);
+
+ assertThat(blobInfo.getLeasees().getLeaseeCount()).isGreaterThan(0);
+ assertThat(blobInfo.getLeasees().getLeasee(0).getUid()).isEqualTo(getUid());
+
+ // Check that lease expiry time is reasonable
+ final long leaseExpiryMs = blobInfo.getLeasees().getLeasee(
+ 0).getLeaseExpiryTimestampMillis();
+ assertThat(leaseExpiryMs).isGreaterThan(testStartTimeMs + BLOB_LEASE_EXPIRY_DURATION_MS);
+ assertThat(leaseExpiryMs).isLessThan(testEndTimeMs + BLOB_LEASE_EXPIRY_DURATION_MS);
+ }
+
private void assertDataUsageAtomDataExpected(long rxb, long txb, long rxp, long txp) {
assertThat(rxb).isGreaterThan(0L);
assertThat(txb).isGreaterThan(0L);
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index 572f9e7..a966d2b 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -1465,7 +1465,7 @@
public void testCanBubble_ranking() throws Exception {
if ((mActivityManager.isLowRamDevice() && !FeatureUtil.isWatch())
- || FeatureUtil.isAutomotive()) {
+ || FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
return;
}
@@ -2876,8 +2876,8 @@
public void testNotificationManagerBubblePolicy_flag_intentBubble()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -2896,8 +2896,8 @@
public void testNotificationManagerBubblePolicy_noFlag_service()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
Intent serviceIntent = new Intent(mContext, BubblesTestService.class);
@@ -2922,8 +2922,8 @@
public void testNotificationManagerBubblePolicy_noFlag_phonecall()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
Intent serviceIntent = new Intent(mContext, BubblesTestService.class);
@@ -2948,8 +2948,8 @@
}
public void testNotificationManagerBubblePolicy_noFlag_foreground() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -2975,8 +2975,8 @@
public void testNotificationManagerBubble_checkActivityFlagsDocumentLaunchMode()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3016,8 +3016,8 @@
public void testNotificationManagerBubblePolicy_flag_shortcutBubble()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3041,8 +3041,8 @@
public void testNotificationManagerBubblePolicy_noFlag_invalidShortcut()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3066,8 +3066,8 @@
public void testNotificationManagerBubblePolicy_noFlag_invalidNotif()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3089,8 +3089,8 @@
}
public void testNotificationManagerBubblePolicy_appAll_globalOn() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3112,8 +3112,8 @@
}
public void testNotificationManagerBubblePolicy_appAll_globalOff() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3134,8 +3134,8 @@
}
public void testNotificationManagerBubblePolicy_appAll_channelNo() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3156,8 +3156,8 @@
}
public void testNotificationManagerBubblePolicy_appSelected_channelNo() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3178,8 +3178,8 @@
}
public void testNotificationManagerBubblePolicy_appSelected_channelYes() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3201,8 +3201,8 @@
}
public void testNotificationManagerBubblePolicy_appNone_channelNo() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
@@ -3224,8 +3224,8 @@
public void testNotificationManagerBubblePolicy_noFlag_shortcutRemoved()
throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
@@ -3251,8 +3251,8 @@
}
public void testNotificationManagerBubbleNotificationSuppression() throws Exception {
- if (FeatureUtil.isAutomotive()) {
- // Automotive does not support notification bubbles.
+ if (FeatureUtil.isAutomotive() || FeatureUtil.isTV()) {
+ // These do not support bubbles.
return;
}
try {
diff --git a/tests/backup/AndroidTest.xml b/tests/backup/AndroidTest.xml
index 1f99fdb..ec0ade5 100644
--- a/tests/backup/AndroidTest.xml
+++ b/tests/backup/AndroidTest.xml
@@ -27,6 +27,7 @@
-remove SwitchUserTargetPreparer
-->
<option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
<target_preparer class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
<option name="user-type" value="system" />
</target_preparer>
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java b/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
index f58152e..850870a 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/ConfigChangeTests.java
@@ -160,17 +160,13 @@
+ " in landscape and reverse-landscape", sameSize);
}
- private ActivityLifecycleCounts getLifecycleCountsForRotation(ComponentName activityName,
- RotationSession session, int before, int after, boolean canHandleConfigChange) {
- final int currentRotation = mWmState.getRotation();
- // The test verifies the events from "before" rotation to "after" rotation. So when
- // preparing "before" rotation, the changes should be consumed to avoid being mixed into
- // the result to verify.
- final boolean is90DegreeDelta = Math.abs(currentRotation - before) % 2 != 0;
+ private void prepareRotation(ComponentName activityName, RotationSession session,
+ int currentRotation, int initialRotation, boolean canHandleConfigChange) {
+ final boolean is90DegreeDelta = Math.abs(currentRotation - initialRotation) % 2 != 0;
if (is90DegreeDelta) {
separateTestJournal();
}
- session.set(before);
+ session.set(initialRotation);
if (is90DegreeDelta) {
// Consume the changes of "before" rotation to make sure the activity is in a stable
// state to apply "after" rotation.
@@ -181,6 +177,15 @@
.countWithRetry("activity rotated with 90 degree delta",
countSpec(expectedCallback, CountSpec.GREATER_THAN, 0)));
}
+ }
+
+ private ActivityLifecycleCounts getLifecycleCountsForRotation(ComponentName activityName,
+ RotationSession session, int before, int after, boolean canHandleConfigChange) {
+ final int currentRotation = mWmState.getRotation();
+ // The test verifies the events from "before" rotation to "after" rotation. So when
+ // preparing "before" rotation, the changes should be consumed to avoid being mixed into
+ // the result to verify.
+ prepareRotation(activityName, session, currentRotation, before, canHandleConfigChange);
separateTestJournal();
session.set(after);
mWmState.computeState(activityName);
@@ -202,13 +207,12 @@
private void testRotation(ComponentName activityName, int rotationStep, int numRelaunch,
int numConfigChange) {
launchActivity(activityName);
-
mWmState.computeState(activityName);
final int initialRotation = 4 - rotationStep;
final RotationSession rotationSession = createManagedRotationSession();
- rotationSession.set(initialRotation);
- mWmState.computeState(activityName);
+ prepareRotation(activityName, rotationSession, mWmState.getRotation(), initialRotation,
+ numConfigChange > 0);
final int actualStackId =
mWmState.getTaskByActivity(activityName).mRootTaskId;
final int displayId = mWmState.getRootTask(actualStackId).mDisplayId;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
index 7075f4c..a876088 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplitScreenTests.java
@@ -208,6 +208,7 @@
// Make sure docked stack is focused. This way when we dismiss it later fullscreen stack
// will come up.
+ launchActivity(LAUNCHING_ACTIVITY, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
launchActivity(TEST_ACTIVITY, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
// Move activity back to fullscreen stack.
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
index ae9a40c..bdb28b2 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
@@ -135,7 +135,10 @@
sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_1, DEFAULT_DISPLAY);
assumeTrue(supportsMultiDisplay());
- final InvisibleVirtualDisplaySession session = createManagedInvisibleDisplaySession();
+
+ // VirtualDisplay can't maintain perDisplayFocus because it is not trusted,
+ // so uses SimulatedDisplay instead.
+ final SimulatedDisplaySession session = createManagedSimulatedDisplaySession();
final int secondaryDisplayId = session.getDisplayId();
final SecondaryActivity secondaryActivity = session.startActivityAndFocus();
sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_2, INVALID_DISPLAY);
@@ -497,13 +500,7 @@
}
SecondaryActivity startActivityAndFocus() {
- final int displayId = getDisplayId();
- // An untrusted virtual display won't have focus until the display is touched.
- final SecondaryActivity activity = WindowManagerTestBase.startActivity(
- SecondaryActivity.class, displayId, false /* hasFocus */);
- tapOnCenterOfDisplay(displayId);
- activity.waitAndAssertWindowFocusState(true);
- return activity;
+ return WindowFocusTests.startActivityAndFocus(getDisplayId(), false /* hasFocus */);
}
@Override
@@ -516,4 +513,40 @@
}
}
}
+
+ private SimulatedDisplaySession createManagedSimulatedDisplaySession() {
+ return mObjectTracker.manage(new SimulatedDisplaySession());
+ }
+
+ private class SimulatedDisplaySession implements AutoCloseable {
+ private final VirtualDisplaySession mVirtualDisplaySession;
+ private final WindowManagerState.DisplayContent mVirtualDisplay;
+
+ SimulatedDisplaySession() {
+ mVirtualDisplaySession = new VirtualDisplaySession();
+ mVirtualDisplay = mVirtualDisplaySession.setSimulateDisplay(true).createDisplay();
+ }
+
+ int getDisplayId() {
+ return mVirtualDisplay.mId;
+ }
+
+ SecondaryActivity startActivityAndFocus() {
+ return WindowFocusTests.startActivityAndFocus(getDisplayId(), true /* hasFocus */);
+ }
+
+ @Override
+ public void close() {
+ mVirtualDisplaySession.close();
+ }
+ }
+
+ private static SecondaryActivity startActivityAndFocus(int displayId, boolean hasFocus) {
+ // An untrusted virtual display won't have focus until the display is touched.
+ final SecondaryActivity activity = WindowManagerTestBase.startActivity(
+ SecondaryActivity.class, displayId, hasFocus);
+ tapOnCenterOfDisplay(displayId);
+ activity.waitAndAssertWindowFocusState(true);
+ return activity;
+ }
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
index 24636e3..04e96ad 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationControllerTests.java
@@ -19,6 +19,7 @@
import static android.server.wm.WindowInsetsAnimationControllerTests.ControlListener.Event.CANCELLED;
import static android.server.wm.WindowInsetsAnimationControllerTests.ControlListener.Event.FINISHED;
import static android.server.wm.WindowInsetsAnimationControllerTests.ControlListener.Event.READY;
+import static android.server.wm.WindowInsetsAnimationTestBase.showImeWithHardKeyboardSetting;
import static android.server.wm.WindowInsetsAnimationUtils.INSETS_EVALUATOR;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.navigationBars;
@@ -26,8 +27,6 @@
import static androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
@@ -124,6 +123,7 @@
mActivity = startActivity(TestActivity.class);
mRootView = mActivity.getWindow().getDecorView();
mListener = new ControlListener(mErrorCollector);
+ showImeWithHardKeyboardSetting(mObjectTracker);
assumeTestCompatibility();
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
index 6fe77e4..da69b92 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsAnimationTestBase.java
@@ -34,11 +34,13 @@
import static org.mockito.Mockito.spy;
import android.os.Bundle;
+import android.provider.Settings;
+import android.server.wm.WindowInsetsAnimationTestBase.AnimCallback.AnimationStep;
+import android.server.wm.settings.SettingsSession;
import android.util.ArraySet;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
-import android.server.wm.WindowInsetsAnimationTestBase.AnimCallback.AnimationStep;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -154,6 +156,23 @@
}
}
+ /**
+ * Workaround for b/158637229: force the keyboard to show even when there is a hardware keyboard
+ * during IME related insets tests to avoid issues when testing on devices that have a hardware
+ * keyboard.
+ *
+ * @param tracker the test's {@link ObjectTracker}, used to clean up the setting override after
+ * the test finishes.
+ */
+ static void showImeWithHardKeyboardSetting(ObjectTracker tracker) {
+ final SettingsSession<Integer> showImeWithHardKeyboardSetting = new SettingsSession<>(
+ Settings.Secure.getUriFor(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD),
+ Settings.Secure::getInt,
+ Settings.Secure::putInt);
+ tracker.manage(showImeWithHardKeyboardSetting);
+ showImeWithHardKeyboardSetting.set(1);
+ }
+
public static class AnimCallback extends WindowInsetsAnimation.Callback {
public static class AnimationStep {
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
index 0f29d97..6dc0c7b 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsControllerTests.java
@@ -17,6 +17,7 @@
package android.server.wm;
import static android.graphics.PixelFormat.TRANSLUCENT;
+import static android.server.wm.WindowInsetsAnimationTestBase.showImeWithHardKeyboardSetting;
import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE;
@@ -40,6 +41,8 @@
import android.app.Activity;
import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
@@ -78,6 +81,9 @@
private final static long TIME_SLICE = 50; // milliseconds
private final static AnimationCallback ANIMATION_CALLBACK = new AnimationCallback();
+ private static final String AM_BROADCAST_CLOSE_SYSTEM_DIALOGS =
+ "am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS";
+
@Rule
public final ErrorCollector mErrorCollector = new ErrorCollector();
@@ -175,6 +181,8 @@
@Test
public void testImeShowAndHide() {
+ showImeWithHardKeyboardSetting(mObjectTracker);
+
final TestActivity activity = startActivity(TestActivity.class);
final View rootView = activity.getWindow().getDecorView();
getInstrumentation().runOnMainSync(() -> {
@@ -394,6 +402,12 @@
// Swiping from top of display can show bars.
dragFromTopToCenter(rootView);
PollingCheck.waitFor(TIMEOUT, () -> rootView.getRootWindowInsets().isVisible(types));
+
+ // The swipe action brings down the notification shade which causes subsequent tests to
+ // fail.
+ if (isAutomotive(mContext)) {
+ broadcastCloseSystemDialogs();
+ }
}
@Test
@@ -448,6 +462,8 @@
@Test
public void testShowImeOnCreate() throws Exception {
+ showImeWithHardKeyboardSetting(mObjectTracker);
+
final TestShowOnCreateActivity activity = startActivity(TestShowOnCreateActivity.class);
final View rootView = activity.getWindow().getDecorView();
ANIMATION_CALLBACK.waitForFinishing(TIMEOUT);
@@ -509,6 +525,14 @@
}
+ private static void broadcastCloseSystemDialogs() {
+ executeShellCommand(AM_BROADCAST_CLOSE_SYSTEM_DIALOGS);
+ }
+
+ private static boolean isAutomotive(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ }
+
private static void hideInsets(View view, int types) throws InterruptedException {
ANIMATION_CALLBACK.reset();
getInstrumentation().runOnMainSync(() -> {
diff --git a/tests/tests/appenumeration/AndroidTest.xml b/tests/tests/appenumeration/AndroidTest.xml
index bc8d224..2932d51 100644
--- a/tests/tests/appenumeration/AndroidTest.xml
+++ b/tests/tests/appenumeration/AndroidTest.xml
@@ -48,6 +48,7 @@
<option name="test-file-name" value="CtsAppEnumerationQueriesPackage.apk" />
<option name="test-file-name" value="CtsAppEnumerationQueriesNothingTargetsQ.apk" />
<option name="test-file-name" value="CtsAppEnumerationQueriesNothingHasPermission.apk" />
+ <option name="test-file-name" value="CtsAppEnumerationQueriesNothingHasProvider.apk" />
<option name="test-file-name" value="CtsAppEnumerationWildcardBrowsableActivitySource.apk" />
<option name="test-file-name" value="CtsAppEnumerationWildcardContactsActivitySource.apk" />
<option name="test-file-name" value="CtsAppEnumerationWildcardDocumentEditorActivitySource.apk" />
diff --git a/tests/tests/appenumeration/app/source/Android.bp b/tests/tests/appenumeration/app/source/Android.bp
index 8c95b27..cfa3871 100644
--- a/tests/tests/appenumeration/app/source/Android.bp
+++ b/tests/tests/appenumeration/app/source/Android.bp
@@ -164,6 +164,18 @@
}
android_test_helper_app {
+ name: "CtsAppEnumerationQueriesNothingHasProvider",
+ manifest: "AndroidManifest-queriesNothing-hasProvider.xml",
+ defaults: ["CtsAppEnumerationQueriesDefaults"],
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "vts10",
+ "general-tests",
+ ],
+}
+
+android_test_helper_app {
name: "CtsAppEnumerationSharedUidSource",
manifest: "AndroidManifest-queriesNothing-sharedUser.xml",
defaults: ["CtsAppEnumerationQueriesDefaults"],
diff --git a/tests/tests/appenumeration/app/source/AndroidManifest-queriesNothing-hasProvider.xml b/tests/tests/appenumeration/app/source/AndroidManifest-queriesNothing-hasProvider.xml
new file mode 100644
index 0000000..1e94c1b
--- /dev/null
+++ b/tests/tests/appenumeration/app/source/AndroidManifest-queriesNothing-hasProvider.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.appenumeration.queries.nothing.hasprovider">
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="android.appenumeration.cts.query.TestActivity"
+ android:exported="true" />
+ <provider android:name="android.appenumeration.cts.query.TestProvider"
+ android:authorities="android.appenumeration.queries.nothing.hasprovider"
+ android:exported="true" >
+
+ </provider>
+ </application>
+</manifest>
diff --git a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
index 3e9d789..a4ae8b2 100644
--- a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
+++ b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestActivity.java
@@ -43,25 +43,41 @@
import android.content.IntentSender;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.PatternMatcher;
import android.os.RemoteCallback;
import android.util.SparseArray;
+import java.util.ArrayList;
+
public class TestActivity extends Activity {
SparseArray<RemoteCallback> callbacks = new SparseArray<>();
private Handler mainHandler;
+ private Handler backgroundHandler;
+ private HandlerThread backgroundThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
mainHandler = new Handler(getMainLooper());
+ backgroundThread = new HandlerThread("testBackground");
+ backgroundThread.start();
+ backgroundHandler = new Handler(backgroundThread.getLooper());
super.onCreate(savedInstanceState);
handleIntent(getIntent());
}
+ @Override
+ protected void onDestroy() {
+ backgroundThread.quitSafely();
+ super.onDestroy();
+ }
+
private void handleIntent(Intent intent) {
RemoteCallback remoteCallback = intent.getParcelableExtra(EXTRA_REMOTE_CALLBACK);
try {
@@ -123,6 +139,9 @@
final String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
awaitPackageBroadcast(
remoteCallback, packageName, Intent.ACTION_PACKAGE_ADDED, 3000);
+ } else if (Constants.ACTION_QUERY_RESOLVER.equals(action)) {
+ final String authority = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME);
+ queryResolverForVisiblePackages(remoteCallback, authority);
} else {
sendError(remoteCallback, new Exception("unknown action " + action));
}
@@ -199,6 +218,33 @@
finish();
}
+ private void queryResolverForVisiblePackages(RemoteCallback remoteCallback, String authority) {
+ backgroundHandler.post(() -> {
+ Uri queryUri = Uri.parse("content://" + authority + "/test");
+ Cursor query = getContentResolver().query(queryUri, null, null, null, null);
+ if (query == null || !query.moveToFirst()) {
+ sendError(remoteCallback,
+ new IllegalStateException(
+ "Query of " + queryUri + " could not be completed"));
+ return;
+ }
+ ArrayList<String> visiblePackages = new ArrayList<>();
+ while (!query.isAfterLast()) {
+ visiblePackages.add(query.getString(0));
+ query.moveToNext();
+ }
+ query.close();
+
+ mainHandler.post(() -> {
+ Bundle result = new Bundle();
+ result.putStringArray(EXTRA_RETURN_RESULT, visiblePackages.toArray(new String[]{}));
+ remoteCallback.sendResult(result);
+ finish();
+ });
+
+ });
+ }
+
private void sendError(RemoteCallback remoteCallback, Exception failure) {
Bundle result = new Bundle();
result.putSerializable(EXTRA_ERROR, failure);
diff --git a/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestProvider.java b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestProvider.java
new file mode 100644
index 0000000..b5bc7f0
--- /dev/null
+++ b/tests/tests/appenumeration/app/source/src/android/appenumeration/cts/query/TestProvider.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 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.appenumeration.cts.query;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+
+import java.util.Collections;
+
+public class TestProvider extends ContentProvider {
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ MatrixCursor matrixCursor = new MatrixCursor(new String[]{"seenPackage"}, 0);
+ getContext().getPackageManager().getInstalledPackages(0 /*flags*/).forEach(packageInfo -> {
+ matrixCursor.addRow(Collections.singletonList(packageInfo.packageName));
+ });
+ return matrixCursor;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ return 0;
+ }
+}
diff --git a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
index c24744f..460ce09 100644
--- a/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
+++ b/tests/tests/appenumeration/lib/src/android/appenumeration/cts/Constants.java
@@ -43,6 +43,8 @@
public static final String QUERIES_ACTIVITY_ACTION = PKG_BASE + "queries.activity.action";
/** A package that has no queries but gets the QUERY_ALL_PACKAGES permission */
public static final String QUERIES_NOTHING_PERM = PKG_BASE + "queries.nothing.haspermission";
+ /** A package that has no queries but has a provider that can be queried */
+ public static final String QUERIES_NOTHING_PROVIDER = PKG_BASE + "queries.nothing.hasprovider";
/** A package that has no queries tag or permissions but targets Q */
public static final String QUERIES_NOTHING_Q = PKG_BASE + "queries.nothing.q";
/** A package that has no queries tag or permission to query any specific packages */
@@ -127,9 +129,12 @@
PKG_BASE + "cts.action.GET_INSTALLED_PACKAGES";
public static final String ACTION_START_SENDER_FOR_RESULT =
PKG_BASE + "cts.action.START_SENDER_FOR_RESULT";
+ public static final String ACTION_QUERY_RESOLVER =
+ PKG_BASE + "cts.action.QUERY_RESOLVER_FOR_VISIBILITY";
public static final String EXTRA_REMOTE_CALLBACK = "remoteCallback";
public static final String EXTRA_ERROR = "error";
public static final String EXTRA_FLAGS = "flags";
public static final String EXTRA_DATA = "data";
+ public static final String EXTRA_AUTHORITY = "authority";
}
diff --git a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
index fe9b79d..cbea10a 100644
--- a/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
+++ b/tests/tests/appenumeration/src/android/appenumeration/cts/AppEnumerationTests.java
@@ -23,11 +23,13 @@
import static android.appenumeration.cts.Constants.ACTION_MANIFEST_SERVICE;
import static android.appenumeration.cts.Constants.ACTION_QUERY_ACTIVITIES;
import static android.appenumeration.cts.Constants.ACTION_QUERY_PROVIDERS;
+import static android.appenumeration.cts.Constants.ACTION_QUERY_RESOLVER;
import static android.appenumeration.cts.Constants.ACTION_QUERY_SERVICES;
import static android.appenumeration.cts.Constants.ACTION_START_DIRECTLY;
import static android.appenumeration.cts.Constants.ACTION_START_FOR_RESULT;
import static android.appenumeration.cts.Constants.ACTIVITY_CLASS_DUMMY_ACTIVITY;
import static android.appenumeration.cts.Constants.ACTIVITY_CLASS_TEST;
+import static android.appenumeration.cts.Constants.EXTRA_AUTHORITY;
import static android.appenumeration.cts.Constants.EXTRA_DATA;
import static android.appenumeration.cts.Constants.EXTRA_ERROR;
import static android.appenumeration.cts.Constants.EXTRA_FLAGS;
@@ -35,6 +37,7 @@
import static android.appenumeration.cts.Constants.QUERIES_ACTIVITY_ACTION;
import static android.appenumeration.cts.Constants.QUERIES_NOTHING;
import static android.appenumeration.cts.Constants.QUERIES_NOTHING_PERM;
+import static android.appenumeration.cts.Constants.QUERIES_NOTHING_PROVIDER;
import static android.appenumeration.cts.Constants.QUERIES_NOTHING_Q;
import static android.appenumeration.cts.Constants.QUERIES_NOTHING_SHARED_USER;
import static android.appenumeration.cts.Constants.QUERIES_PACKAGE;
@@ -65,6 +68,7 @@
import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
import static org.hamcrest.Matchers.greaterThan;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
@@ -100,6 +104,7 @@
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
+import java.util.Arrays;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -430,6 +435,22 @@
}
}
+ @Test
+ public void queriesResolver_grantsVisibilityToProvider() throws Exception {
+ assertNotVisible(QUERIES_NOTHING_PROVIDER, QUERIES_NOTHING_PERM);
+
+ String[] result = sendCommandBlocking(
+ QUERIES_NOTHING_PERM, QUERIES_NOTHING_PROVIDER, null, ACTION_QUERY_RESOLVER)
+ .getStringArray(Intent.EXTRA_RETURN_RESULT);
+ Arrays.sort(result);
+ assertThat(QUERIES_NOTHING_PERM + " not visible to " + QUERIES_NOTHING_PROVIDER
+ + " during resolver interaction",
+ Arrays.binarySearch(result, QUERIES_NOTHING_PERM),
+ greaterThanOrEqualTo(0));
+
+ assertVisible(QUERIES_NOTHING_PROVIDER, QUERIES_NOTHING_PERM);
+ }
+
private void assertNotVisible(String sourcePackageName, String targetPackageName)
throws Exception {
if (!sGlobalFeatureEnabled) return;
diff --git a/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java b/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java
index 5ad060a..dee467e 100644
--- a/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java
+++ b/tests/tests/graphics/src/android/graphics/cts/FrameRateCtsActivity.java
@@ -48,7 +48,7 @@
}
private static String TAG = "FrameRateCtsActivity";
- private static final long FRAME_RATE_SWITCH_GRACE_PERIOD_SECONDS = 1;
+ private static final long FRAME_RATE_SWITCH_GRACE_PERIOD_SECONDS = 2;
private static final long STABLE_FRAME_RATE_WAIT_SECONDS = 1;
private static final long POST_BUFFER_INTERVAL_MILLIS = 500;
private static final int PRECONDITION_WAIT_MAX_ATTEMPTS = 5;
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index 0946147..2eef41d 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -283,6 +283,12 @@
mLockCredential.gotoKeyguard();
mLockCredential.enterAndConfirmLockCredential();
launchHomeActivity();
+ KeyguardManager keyguardManager = (KeyguardManager)getContext().getSystemService(
+ Context.KEYGUARD_SERVICE);
+ for (int i = 0; i < 25 && keyguardManager.isDeviceLocked(); i++) {
+ SystemClock.sleep(200);
+ }
+ assertFalse(keyguardManager.isDeviceLocked());
}
@Override
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index 46592ca..55ba086 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -1105,17 +1105,16 @@
assertTrue(
signedCertIssuer.toASN1Object().equals(signingCertSubject.toASN1Object()));
+ X500Name signedCertSubject =
+ new JcaX509CertificateHolder(x509PrevCert).getSubject();
if (i == 1) {
// First cert should have subject "CN=Android Keystore Key".
- X500Name signedCertSubject =
- new JcaX509CertificateHolder(x509PrevCert).getSubject();
assertEquals(signedCertSubject, new X500Name("CN=Android Keystore Key"));
} else {
// Only strongbox implementations should have strongbox in the subject line
- assertEquals(expectStrongBox, x509CurrCert.getSubjectDN()
- .getName()
- .toLowerCase()
- .contains("strongbox"));
+ assertEquals(expectStrongBox, signedCertSubject.toString()
+ .toLowerCase()
+ .contains("strongbox"));
}
} catch (InvalidKeyException | CertificateException | NoSuchAlgorithmException
| NoSuchProviderException | SignatureException e) {
diff --git a/tests/tests/net/Android.bp b/tests/tests/net/Android.bp
index 052ab26..2b99a40 100644
--- a/tests/tests/net/Android.bp
+++ b/tests/tests/net/Android.bp
@@ -72,15 +72,15 @@
test_config_template: "AndroidTestTemplate.xml",
}
-// Networking CTS tests that have a min_sdk_version of the latest released SDK. These tests can
-// be installed on release devices at any point in the release cycle and are useful for qualifying
-// mainline modules on release devices.
+// Networking CTS tests that target the latest released SDK. These tests can be installed on release
+// devices at any point in the Android release cycle and are useful for qualifying mainline modules
+// on release devices.
android_test {
name: "CtsNetTestCasesLatestSdk",
defaults: ["CtsNetTestCasesDefaults"],
jni_uses_sdk_apis: true,
min_sdk_version: "29",
- target_sdk_version: "29",
+ target_sdk_version: "30",
test_suites: [
"device-tests",
"mts",
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
index 985e313..6d3db89 100644
--- a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
+++ b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
@@ -68,7 +68,6 @@
mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
mCR = getContext().getContentResolver();
mCtsNetUtils = new CtsNetUtils(getContext());
- mCtsNetUtils.storePrivateDnsSetting();
}
@Override
@@ -223,6 +222,7 @@
@AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
public void testResNApiNXDomainPrivateDns() throws InterruptedException {
+ mCtsNetUtils.storePrivateDnsSetting();
// Enable private DNS strict mode and set server to dns.google before doing NxDomain test.
// b/144521720
try {
diff --git a/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt b/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
index 4517327..773551b 100644
--- a/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
+++ b/tests/tests/os/src/android/os/cts/CompanionDeviceManagerTest.kt
@@ -17,23 +17,31 @@
package android.os.cts
import android.companion.CompanionDeviceManager
+import android.content.pm.PackageManager.FEATURE_COMPANION_DEVICE_SETUP
import android.net.MacAddress
import android.platform.test.annotations.AppModeFull
import android.test.InstrumentationTestCase
+import androidx.test.InstrumentationRegistry
+import androidx.test.runner.AndroidJUnit4
import com.android.compatibility.common.util.SystemUtil.runShellCommand
import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
import com.android.compatibility.common.util.ThrowingSupplier
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
const val COMPANION_APPROVE_WIFI_CONNECTIONS =
"android.permission.COMPANION_APPROVE_WIFI_CONNECTIONS"
const val DUMMY_MAC_ADDRESS = "00:00:00:00:00:10"
const val MANAGE_COMPANION_DEVICES = "android.permission.MANAGE_COMPANION_DEVICES"
const val SHELL_PACKAGE_NAME = "com.android.shell"
-val InstrumentationTestCase.context get() = instrumentation.context
+val InstrumentationTestCase.context get() = InstrumentationRegistry.getTargetContext()
/**
* Test for [CompanionDeviceManager]
*/
+@RunWith(AndroidJUnit4::class)
class CompanionDeviceManagerTest : InstrumentationTestCase() {
val cdm by lazy { context.getSystemService(CompanionDeviceManager::class.java) }
@@ -58,7 +66,13 @@
}, *permissions)
}
+ @Before
+ fun assumeHasFeature() {
+ assumeTrue(context.packageManager.hasSystemFeature(FEATURE_COMPANION_DEVICE_SETUP))
+ }
+
@AppModeFull(reason = "Companion API for non-instant apps only")
+ @Test
fun testIsDeviceAssociated() {
val userId = context.userId
val packageName = context.packageName
@@ -78,6 +92,7 @@
}
@AppModeFull(reason = "Companion API for non-instant apps only")
+ @Test
fun testIsDeviceAssociatedWithCompanionApproveWifiConnectionsPermission() {
assertTrue(isCdmAssociated(
DUMMY_MAC_ADDRESS, SHELL_PACKAGE_NAME, MANAGE_COMPANION_DEVICES,
diff --git a/tests/tests/permission/AndroidTest.xml b/tests/tests/permission/AndroidTest.xml
index 102741c..22329e6 100644
--- a/tests/tests/permission/AndroidTest.xml
+++ b/tests/tests/permission/AndroidTest.xml
@@ -19,6 +19,8 @@
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
+
<!-- Install main test suite apk -->
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 82e2a2a..18224dd5 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -65,6 +65,10 @@
private static final String HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PERMISSION
= "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
+ private static final Date MANAGE_COMPANION_DEVICES_PATCH_DATE = parseDate("2020-07-01");
+ private static final String MANAGE_COMPANION_DEVICES_PERMISSION =
+ "android.Manifest.permission.MANAGE_COMPANION_DEVICES";
+
private static final String LOG_TAG = "PermissionProtectionTest";
private static final String PLATFORM_PACKAGE_NAME = "android";
@@ -437,9 +441,14 @@
}
private boolean shouldSkipPermission(String permissionName) {
- return parseDate(SECURITY_PATCH).before(HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PATCH_DATE) &&
- HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PERMISSION.equals(permissionName);
-
+ switch (permissionName) {
+ case HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PERMISSION:
+ return parseDate(SECURITY_PATCH).before(HIDE_NON_SYSTEM_OVERLAY_WINDOWS_PATCH_DATE);
+ case MANAGE_COMPANION_DEVICES_PERMISSION:
+ return parseDate(SECURITY_PATCH).before(MANAGE_COMPANION_DEVICES_PATCH_DATE);
+ default:
+ return false;
+ }
}
private class ExpectedPermissionInfo {
diff --git a/tests/tests/permission3/AndroidTest.xml b/tests/tests/permission3/AndroidTest.xml
index 2e48ea8..557de85 100644
--- a/tests/tests/permission3/AndroidTest.xml
+++ b/tests/tests/permission3/AndroidTest.xml
@@ -25,6 +25,8 @@
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
+
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsPermission3TestCases.apk" />
diff --git a/tests/tests/role/AndroidTest.xml b/tests/tests/role/AndroidTest.xml
index 71a4861..4a8189f 100644
--- a/tests/tests/role/AndroidTest.xml
+++ b/tests/tests/role/AndroidTest.xml
@@ -23,6 +23,7 @@
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
<option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk30ModuleController" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
index a992b9b..c03877c 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
@@ -82,8 +82,8 @@
private static final int MAX_RSRQ = -3;
private static final int MIN_RSRQ = -35;
// Maximum and minimum possible RSSNR values.
- private static final int MAX_RSSNR = 50;
- private static final int MIN_RSSNR = 0;
+ private static final int MAX_RSSNR = 30;
+ private static final int MIN_RSSNR = -20;
// Maximum and minimum possible CQI values.
private static final int MAX_CQI = 30;
private static final int MIN_CQI = 0;
diff --git a/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
index f7160dd..5e2f627 100644
--- a/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -57,8 +57,11 @@
import android.net.TetheringManager.TetheringRequest;
import android.net.cts.util.CtsNetUtils;
import android.net.cts.util.CtsNetUtils.TestNetworkCallback;
+import android.net.wifi.WifiClient;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.SoftApCallback;
import android.os.Bundle;
+import android.os.ConditionVariable;
import android.os.PersistableBundle;
import android.os.ResultReceiver;
import android.telephony.CarrierConfigManager;
@@ -135,6 +138,40 @@
dropShellPermissionIdentity();
}
+ private static class StopSoftApCallback implements SoftApCallback {
+ private final ConditionVariable mWaiting = new ConditionVariable();
+ @Override
+ public void onStateChanged(int state, int failureReason) {
+ if (state == WifiManager.WIFI_AP_STATE_DISABLED) mWaiting.open();
+ }
+
+ @Override
+ public void onConnectedClientsChanged(List<WifiClient> clients) { }
+
+ public void waitForSoftApStopped() {
+ if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
+ fail("stopSoftAp Timeout");
+ }
+ }
+ }
+
+ // Wait for softAp to be disabled. This is necessary on devices where stopping softAp
+ // deletes the interface. On these devices, tethering immediately stops when the softAp
+ // interface is removed, but softAp is not yet fully disabled. Wait for softAp to be
+ // fully disabled, because otherwise the next test might fail because it attempts to
+ // start softAp before it's fully stopped.
+ private void expectSoftApDisabled() {
+ final StopSoftApCallback callback = new StopSoftApCallback();
+ try {
+ mWm.registerSoftApCallback(c -> c.run(), callback);
+ // registerSoftApCallback will immediately call the callback with the current state, so
+ // this callback will fire even if softAp is already disabled.
+ callback.waitForSoftApStopped();
+ } finally {
+ mWm.unregisterSoftApCallback(callback);
+ }
+ }
+
private class TetherChangeReceiver extends BroadcastReceiver {
private class TetherState {
final ArrayList<String> mAvailable;
@@ -294,6 +331,7 @@
mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
mTM.stopTethering(TETHERING_WIFI);
+ expectSoftApDisabled();
mTetherChangeReceiver.expectTethering(false /* active */, wifiRegexs);
}
@@ -544,6 +582,7 @@
private void stopWifiTethering(final TestTetheringEventCallback callback) {
mTM.stopTethering(TETHERING_WIFI);
+ expectSoftApDisabled();
callback.expectTetheredInterfacesChanged(null);
callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 22052e1..6a1c4d6 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -770,17 +770,10 @@
Thread.sleep(1000);
assertEquals("Loaded", mOnUiThread.getTitle());
- // Test that when AppCache is enabled and a valid path is provided, we
- // get an AppCache callback of some kind.
- mSettings.setAppCachePath(getActivity().getDir("appcache", 0).getPath());
- mOnUiThread.loadUrlAndWaitForCompletion(url);
- new PollingCheck(WEBVIEW_TIMEOUT) {
- @Override
- protected boolean check() {
- return mOnUiThread.getTitle() != null
- && mOnUiThread.getTitle().endsWith("Callback");
- }
- }.run();
+ // We used to test that when AppCache is enabled and a valid path is
+ // provided, we got an AppCache callback of some kind, but AppCache is
+ // deprecated on the web and will be removed from Chromium in the
+ // future, so this test has been removed.
}
// Ideally, we need a test case for the enabled case. However, it seems that
diff --git a/tests/tests/wifi/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java b/tests/tests/wifi/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
index 8e316e6..a692f12 100644
--- a/tests/tests/wifi/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/nl80211/cts/WifiNl80211ManagerTest.java
@@ -89,4 +89,12 @@
manager.getTxPacketCounters("wlan0");
} catch (Exception ignore) {}
}
+
+ @Test
+ public void testSetOnServiceDeadCallback() {
+ try {
+ WifiNl80211Manager manager = mContext.getSystemService(WifiNl80211Manager.class);
+ manager.setOnServiceDeadCallback(() -> {});
+ } catch (Exception ignore) {}
+ }
}
diff --git a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
index ca14b0e..fad4230 100644
--- a/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
+++ b/tests/tests/wifi/src/android/net/wifi/rtt/cts/WifiRttTest.java
@@ -247,7 +247,9 @@
assertEquals("Ranging request not success",
result.getStatus(), RangingResult.STATUS_SUCCESS);
ResponderLocation responderLocation = result.getUnverifiedResponderLocation();
- assertNotNull("ResponderLocation should not be null", responderLocation);
+ if (responderLocation == null) {
+ return;
+ }
assertTrue("ResponderLocation is not valid", responderLocation.isLciSubelementValid());
// Check LCI related APIs