summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-01 02:26:02 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-02-01 02:26:02 +0000
commit0464c22aed42158b51064fec7deedd870de2b0b6 (patch)
tree2338f4a4d20ff124c497ad22b42a33d8b56da879
parent4256ce17cbcebb7c225486ee3b9938e064fdb35d (diff)
parent791c816a3518b805f7eda7e266f139976d518a7c (diff)
downloadcts-android-cts-13.0_r7.tar.gz
Merge "Merge cherrypicks of ['android-review.googlesource.com/2905571', 'android-review.googlesource.com/2935030', 'android-review.googlesource.com/2935032'] into sparse-11368268-L86400030001713872. SPARSE_CHANGE: Ia4e8dc1b3ce017d0ac677b6ab447ae11980d33cb SPARSE_CHANGE: Id31098525e11afdffc1099154ec1ae25dd4a686c SPARSE_CHANGE: Ic9c945a10e50f27de6c71716ff134bf68fdee359" into sparse-11368268-L86400030001713872android-cts-13.0_r7
-rw-r--r--apps/CtsVerifier/AndroidManifest.xml3
-rw-r--r--apps/CtsVerifier/res/layout/system_switch.xml32
-rw-r--r--apps/CtsVerifier/res/menu/test_list_menu.xml13
-rw-r--r--apps/CtsVerifier/res/values/strings.xml11
-rw-r--r--apps/CtsVerifier/res/xml/searchable.xml5
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java290
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java51
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java351
-rw-r--r--apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java456
9 files changed, 787 insertions, 425 deletions
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index c2cf1e19b2f..1cf81576523 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -4257,10 +4257,13 @@
android:targetActivity=".TestListActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
+ <action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
+ <meta-data android:name="android.app.searchable"
+ android:resource="@xml/searchable"/>
</activity-alias>
<!-- remove comment from the next activity to see the sample test surfacing in the app -->
diff --git a/apps/CtsVerifier/res/layout/system_switch.xml b/apps/CtsVerifier/res/layout/system_switch.xml
new file mode 100644
index 00000000000..d810f18f684
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/system_switch.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2023 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.
+-->
+
+<!-- Switch button to enable verifier-system plan. -->
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="match_parent"
+ android:orientation="horizontal" >
+ <Switch
+ android:id="@+id/switch_button"
+ android:text="@string/system"
+ android:textOn="@string/system_on"
+ android:textOff="@string/system_off"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_centerVertical="true" />
+</RelativeLayout> \ No newline at end of file
diff --git a/apps/CtsVerifier/res/menu/test_list_menu.xml b/apps/CtsVerifier/res/menu/test_list_menu.xml
index 2c104a0a34b..70982b09263 100644
--- a/apps/CtsVerifier/res/menu/test_list_menu.xml
+++ b/apps/CtsVerifier/res/menu/test_list_menu.xml
@@ -4,7 +4,12 @@
android:id="@+id/switch_item"
android:title="@string/view"
android:actionLayout="@layout/display_mode_switch"
- android:showAsAction="ifRoom" />
+ android:showAsAction="always" />
+ <item
+ android:id="@+id/system_switch_item"
+ android:title="@string/system"
+ android:actionLayout="@layout/system_switch"
+ android:showAsAction="always" />
<item android:id="@+id/clear"
android:icon="@android:drawable/ic_menu_delete"
android:title="@string/clear"
@@ -13,4 +18,10 @@
android:icon="@android:drawable/ic_menu_save"
android:title="@string/export"
android:showAsAction="ifRoom" />
+ <item
+ android:id="@+id/search_test"
+ android:title="@string/search_title"
+ android:actionViewClass="android.widget.SearchView"
+ android:showAsAction="collapseActionView|ifRoom"
+ android:imeOptions="actionSearch" />
</menu>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 5ebb7c14645..5aa2b91fd7c 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -17,7 +17,8 @@
<string name="app_name">CTS Verifier</string>
<string name="module_id">noabi CtsVerifier</string>
- <string name="title_version">CTS Verifier %1$s</string>
+ <string name="title_version">Verifier %1$s</string>
+ <string name="version_number_format">Version #: %d</string>
<string name="pass_button_text">Pass</string>
<string name="info_button_text">Info</string>
@@ -31,6 +32,14 @@
<string name="retry_button_text">Retry</string>
<string name="finish_button_text">Finish</string>
<string name="fail_and_next_button_text">Fail and Next</string>
+ <string name="yes_string">Yes</string>
+ <string name="no_string">No</string>
+ <string name="search_label">TestListActivity</string>
+ <string name="search_hint">Search Tests</string>
+ <string name="search_title">Search</string>
+ <string name="system">System</string>
+ <string name="system_on">ON</string>
+ <string name="system_off">OFF</string>
<!-- Strings for CtsReportLog warning -->
<string name="reportlog_warning_title">CTS-Verifier Report Log</string>
diff --git a/apps/CtsVerifier/res/xml/searchable.xml b/apps/CtsVerifier/res/xml/searchable.xml
new file mode 100644
index 00000000000..a443c076ee3
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/searchable.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<searchable xmlns:android="http://schemas.android.com/apk/res/android"
+ android:label="@string/search_label"
+ android:hint="@string/search_hint" >
+</searchable> \ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
index e9a3e0d8e9c..5a29690c9c0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java
@@ -17,7 +17,6 @@
package com.android.cts.verifier;
import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
-import static com.android.cts.verifier.TestListActivity.sInitialLaunch;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -28,8 +27,8 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.hardware.SensorPrivacyManager;
-import android.os.Bundle;
import android.os.BatteryManager;
+import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.ListView;
@@ -45,76 +44,69 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
/**
- * {@link TestListAdapter} that populates the {@link TestListActivity}'s {@link ListView} by
- * reading data from the CTS Verifier's AndroidManifest.xml.
- * <p>
- * Making a new test activity to appear in the list requires the following steps:
+ * {@link TestListAdapter} that populates the {@link TestListActivity}'s {@link ListView} by reading
+ * data from the CTS Verifier's AndroidManifest.xml.
+ *
+ * <p>Making a new test activity to appear in the list requires the following steps:
*
* <ol>
- * <li>REQUIRED: Add an activity to the AndroidManifest.xml with an intent filter with a
- * main action and the MANUAL_TEST category.
- * <pre>
+ * <li>REQUIRED: Add an activity to the AndroidManifest.xml with an intent filter with a main
+ * action and the MANUAL_TEST category.
+ * <pre>
* <intent-filter>
* <action android:name="android.intent.action.MAIN" />
* <category android:name="android.cts.intent.category.MANUAL_TEST" />
* </intent-filter>
* </pre>
- * </li>
- * <li>REQUIRED: Add a meta data attribute to indicate which display modes of tests the activity
- * should belong to. "single_display_mode" indicates a test is only needed to run on the
- * main display mode (i.e. unfolded), and "multi_display_mode" indicates a test is required
- * to run under both modes (i.e. both folded and unfolded).If you don't add this attribute,
- * your test will show up in both unfolded and folded modes.
- * <pre>
+ * <li>REQUIRED: Add a meta data attribute to indicate which display modes of tests the activity
+ * should belong to. "single_display_mode" indicates a test is only needed to run on the main
+ * display mode (i.e. unfolded), and "multi_display_mode" indicates a test is required to run
+ * under both modes (i.e. both folded and unfolded).If you don't add this attribute, your test
+ * will show up in both unfolded and folded modes.
+ * <pre>
* <meta-data android:name="display_mode" android:value="multi_display_mode" />
* </pre>
- * </li>
- * <li>OPTIONAL: Add a meta data attribute to indicate what category of tests the activity
- * should belong to. If you don't add this attribute, your test will show up in the
- * "Other" tests category.
- * <pre>
+ * <li>OPTIONAL: Add a meta data attribute to indicate what category of tests the activity should
+ * belong to. If you don't add this attribute, your test will show up in the "Other" tests
+ * category.
+ * <pre>
* <meta-data android:name="test_category" android:value="@string/test_category_security" />
* </pre>
- * </li>
- * <li>OPTIONAL: Add a meta data attribute to indicate whether this test has a parent test.
- * <pre>
+ * <li>OPTIONAL: Add a meta data attribute to indicate whether this test has a parent test.
+ * <pre>
* <meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
* </pre>
- * </li>
- * <li>OPTIONAL: Add a meta data attribute to indicate what features are required to run the
- * test. If the device does not have all of the required features then it will not appear
- * in the test list. Use a colon (:) to specify multiple required features.
- * <pre>
+ * <li>OPTIONAL: Add a meta data attribute to indicate what features are required to run the test.
+ * If the device does not have all of the required features then it will not appear in the
+ * test list. Use a colon (:) to specify multiple required features.
+ * <pre>
* <meta-data android:name="test_required_features" android:value="android.hardware.sensor.accelerometer" />
* </pre>
- * </li>
- * <li>OPTIONAL: Add a meta data attribute to indicate features such that, if any present, the
- * test gets excluded from being shown. If the device has any of the excluded features then
- * the test will not appear in the test list. Use a colon (:) to specify multiple features
- * to exclude for the test. Note that the colon means "or" in this case.
- * <pre>
+ * <li>OPTIONAL: Add a meta data attribute to indicate features such that, if any present, the
+ * test gets excluded from being shown. If the device has any of the excluded features then
+ * the test will not appear in the test list. Use a colon (:) to specify multiple features to
+ * exclude for the test. Note that the colon means "or" in this case.
+ * <pre>
* <meta-data android:name="test_excluded_features" android:value="android.hardware.type.television" />
* </pre>
- * </li>
- * <li>OPTIONAL: Add a meta data attribute to indicate features such that, if any present,
- * the test is applicable to run. If the device has any of the applicable features then
- * the test will appear in the test list. Use a colon (:) to specify multiple features
- * <pre>
+ * <li>OPTIONAL: Add a meta data attribute to indicate features such that, if any present, the
+ * test is applicable to run. If the device has any of the applicable features then the test
+ * will appear in the test list. Use a colon (:) to specify multiple features
+ * <pre>
* <meta-data android:name="test_applicable_features" android:value="android.hardware.sensor.compass" />
* </pre>
- * </li>
- * <li>OPTIONAL: Add a meta data attribute to indicate which intent actions are required to run
- * the test. If the device does not have activities that handle all those actions, then it
- * will not appear in the test list. Use a colon (:) to specify multiple required intent actions.
- * <pre>
+ * <li>OPTIONAL: Add a meta data attribute to indicate which intent actions are required to run
+ * the test. If the device does not have activities that handle all those actions, then it
+ * will not appear in the test list. Use a colon (:) to specify multiple required intent
+ * actions.
+ * <pre>
* <meta-data android:name="test_required_actions" android:value="android.app.action.ADD_DEVICE_ADMIN" />
* </pre>
- * </li>
- *
* </ol>
*/
public class ManifestTestListAdapter extends TestListAdapter {
@@ -154,20 +146,50 @@ public class ManifestTestListAdapter extends TestListAdapter {
private static final String CONFIG_CHANGEABLE_VOLUME = "config_changeable_volume";
- /** The config to represent that a test is only needed to run in the main display mode
- * (i.e. unfolded) */
+ /**
+ * The config to represent that a test is only needed to run in the main display mode (i.e.
+ * unfolded).
+ */
private static final String SINGLE_DISPLAY_MODE = "single_display_mode";
- /** The config to represent that a test is needed to run in the multiple display modes
- * (i.e. both unfolded and folded) */
+ /**
+ * The config to represent that a test is needed to run in the multiple display modes (i.e. both
+ * unfolded and folded).
+ */
private static final String MULTIPLE_DISPLAY_MODE = "multi_display_mode";
+ /** The config to represent that a test is only needed to run in the folded display mode. */
+ private static final String FOLDED_DISPLAY_MODE = "folded_display_mode";
+
+ /**
+ * The config to represent that a test is marked as pass when it passes either in folded mode or
+ * in unfolded mode.
+ */
+ private static final String EITHER_MODE = "either_mode";
+
+ /**
+ * The user is not a {@link UserManager#isProfile() profile} and is running in the background,
+ * but {@link UserManager#isUserVisible() visible} in a display.
+ */
+ private static final String USER_TYPE_VISIBLE_BG_USER = "visible_background_non-profile_user";
+
+ /** The name of the camera ITS test of a {@link TestListItem}. */
+ private static final String CAMERA_ITS_TEST =
+ "com.android.cts.verifier.camera.its.ItsTestActivity";
+
+ /** The name of the camera ITS test (folded mode) of a {@link TestListItem}. */
+ private static final String CAMERA_ITS_TEST_FOLDED = CAMERA_ITS_TEST + "[folded]";
+
private final HashSet<String> mDisabledTests;
private Context mContext;
private String mTestParent;
+ public ManifestTestListAdapter(Context context, String testParent) {
+ this(context, testParent, context.getResources().getStringArray(R.array.disabled_tests));
+ }
+
public ManifestTestListAdapter(Context context, String testParent, String[] disabledTestArray) {
super(context);
mContext = context;
@@ -178,36 +200,33 @@ public class ManifestTestListAdapter extends TestListAdapter {
}
}
- public ManifestTestListAdapter(Context context, String testParent) {
- this(context, testParent, context.getResources().getStringArray(R.array.disabled_tests));
- }
-
@Override
protected List<TestListItem> getRows() {
- List<TestListItem> allRows = new ArrayList<TestListItem>();
-
// When launching at the first time or after killing the process, needs to fetch the
// test items of all display modes as the bases for switching.
if (mDisplayModesTests.isEmpty()) {
for (DisplayMode mode : DisplayMode.values()) {
- allRows = getRowsWithDisplayMode(mode.toString());
- mDisplayModesTests.put(mode.toString(), allRows);
+ mDisplayModesTests.put(mode.toString(), getRowsWithDisplayMode(mode.toString()));
}
}
- if (!sInitialLaunch) {
- return getRowsWithDisplayMode(sCurrentDisplayMode);
+ if (mTestFilter != null || TestListActivity.getIsSystemEnabled()) {
+ // Filter test rows dynamically when the filter is specified or verifier-system plan is
+ // enabled.
+ return getRowsWithDisplayMode(sCurrentDisplayMode.toString());
+ } else {
+ return mDisplayModesTests.getOrDefault(
+ sCurrentDisplayMode.toString(), new ArrayList<>());
}
- return allRows;
}
/**
* Gets all rows based on the specific display mode.
*
- * @param mode Given display mode.
- * @return A list containing all test itmes in the given display mode.
+ * @param mode the given display mode
+ * @return a list containing all test itmes in the given display mode
*/
- private List<TestListItem> getRowsWithDisplayMode (String mode) {
+ private List<TestListItem> getRowsWithDisplayMode(String mode) {
/*
* 1. Get all the tests belonging to the test parent.
* 2. Get all the tests keyed by their category.
@@ -236,8 +255,9 @@ public class ManifestTestListAdapter extends TestListAdapter {
mainIntent.setPackage(mContext.getPackageName());
PackageManager packageManager = mContext.getPackageManager();
- List<ResolveInfo> list = packageManager.queryIntentActivities(mainIntent,
- PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
+ List<ResolveInfo> list =
+ packageManager.queryIntentActivities(
+ mainIntent, PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
int size = list.size();
List<ResolveInfo> matchingList = new ArrayList<>();
@@ -272,9 +292,17 @@ public class ManifestTestListAdapter extends TestListAdapter {
String[] applicableFeatures = getApplicableFeatures(info.activityInfo.metaData);
String displayMode = getDisplayMode(info.activityInfo.metaData);
- TestListItem item = TestListItem.newTest(title, testName, intent, requiredFeatures,
- requiredConfigs, requiredActions, excludedFeatures, applicableFeatures,
- displayMode);
+ TestListItem item =
+ TestListItem.newTest(
+ title,
+ testName,
+ intent,
+ requiredFeatures,
+ requiredConfigs,
+ requiredActions,
+ excludedFeatures,
+ applicableFeatures,
+ displayMode);
String testCategory = getTestCategory(mContext, info.activityInfo.metaData);
addTestToCategory(testsByCategory, testCategory, item);
@@ -367,8 +395,8 @@ public class ManifestTestListAdapter extends TestListAdapter {
/**
* Gets the configuration of the display mode per test. The default value is multi_display_mode.
*
- * @param metaData Given metadata of the display mode.
- * @return A string representing the display mode of the test.
+ * @param metaData the given metadata of the display mode
+ * @return a string representing the display mode of the test
*/
static String getDisplayMode(Bundle metaData) {
if (metaData == null) {
@@ -392,8 +420,10 @@ public class ManifestTestListAdapter extends TestListAdapter {
return intent;
}
- static void addTestToCategory(Map<String, List<TestListItem>> testsByCategory,
- String testCategory, TestListItem item) {
+ static void addTestToCategory(
+ Map<String, List<TestListItem>> testsByCategory,
+ String testCategory,
+ TestListItem item) {
List<TestListItem> tests;
if (testsByCategory.containsKey(testCategory)) {
tests = testsByCategory.get(testCategory);
@@ -444,17 +474,18 @@ public class ManifestTestListAdapter extends TestListAdapter {
return true;
}
- private boolean matchAllConfigs(String[] configs) {
+ private boolean matchAllConfigs(Context context, String[] configs) {
if (configs != null) {
for (String config : configs) {
switch (config) {
case CONFIG_NO_EMULATOR:
try {
- Method getStringMethod = ClassLoader.getSystemClassLoader()
- .loadClass("android.os.SystemProperties")
- .getMethod("get", String.class);
- String emulatorKernel = (String) getStringMethod.invoke("0",
- "ro.boot.qemu");
+ Method getStringMethod =
+ ClassLoader.getSystemClassLoader()
+ .loadClass("android.os.SystemProperties")
+ .getMethod("get", String.class);
+ String emulatorKernel =
+ (String) getStringMethod.invoke("0", "ro.boot.qemu");
if (emulatorKernel.equals("1")) {
return false;
}
@@ -463,14 +494,14 @@ public class ManifestTestListAdapter extends TestListAdapter {
}
break;
case CONFIG_VOICE_CAPABLE:
- TelephonyManager telephonyManager = mContext.getSystemService(
- TelephonyManager.class);
+ TelephonyManager telephonyManager =
+ mContext.getSystemService(TelephonyManager.class);
if (!telephonyManager.isVoiceCapable()) {
return false;
}
break;
case CONFIG_HAS_RECENTS:
- if (!getSystemResourceFlag("config_hasRecents")) {
+ if (!getSystemResourceFlag(context, "config_hasRecents")) {
return false;
}
break;
@@ -493,7 +524,7 @@ public class ManifestTestListAdapter extends TestListAdapter {
}
break;
case CONFIG_QUICK_SETTINGS_SUPPORTED:
- if (!getSystemResourceFlag("config_quickSettingsSupported")) {
+ if (!getSystemResourceFlag(context, "config_quickSettingsSupported")) {
return false;
}
break;
@@ -502,7 +533,7 @@ public class ManifestTestListAdapter extends TestListAdapter {
case CONFIG_HAS_CAMERA_TOGGLE:
return isHardwareToggleSupported(SensorPrivacyManager.Sensors.CAMERA);
case CONFIG_CHANGEABLE_VOLUME:
- return !getSystemResourceFlag("config_useFixedVolume");
+ return !getSystemResourceFlag(context, "config_useFixedVolume");
default:
break;
}
@@ -512,11 +543,11 @@ public class ManifestTestListAdapter extends TestListAdapter {
}
/**
- * Check if the test should be ran by the given display mode.
+ * Checks if the test should be ran by the given display mode.
*
- * @param mode Configs of the display mode.
- * @param currentMode Given display mode.
- * @return True if the given display mode matches the configs, otherwise, return false;
+ * @param mode the display mode config of the test
+ * @param currentMode the given display mode
+ * @return true if the given display mode matches the configs, otherwise, return false
*/
private boolean matchDisplayMode(String mode, String currentMode) {
if (mode == null) {
@@ -532,8 +563,33 @@ public class ManifestTestListAdapter extends TestListAdapter {
}
}
- private boolean getSystemResourceFlag(String key) {
- final Resources systemRes = mContext.getResources().getSystem();
+ /** Checks whether the title of the test matches the test filter. */
+ private boolean macthTestFilter(String testTitle) {
+ if (mTestFilter == null) {
+ return true;
+ }
+ return testTitle != null
+ && testTitle
+ .toLowerCase(Locale.getDefault())
+ .contains(mTestFilter.toLowerCase(Locale.getDefault()));
+ }
+
+ /**
+ * Checks whether the test matches the current status of verifier-system plan.
+ *
+ * <p>When verifier-system plan is disabled, all CTS-V tests are shown.
+ *
+ * <p>When verifier-system plan is enabled, specific tests are filtered out, e.g., camera ITS.
+ */
+ private static boolean matchSystemPlanStatus(String testName) {
+ if (testName == null || !TestListActivity.getIsSystemEnabled()) {
+ return true;
+ }
+ return !testName.equals(CAMERA_ITS_TEST) && !testName.equals(CAMERA_ITS_TEST_FOLDED);
+ }
+
+ private static boolean getSystemResourceFlag(Context context, String key) {
+ final Resources systemRes = context.getResources().getSystem();
final int id = systemRes.getIdentifier(key, "bool", "android");
if (id == Resources.ID_NULL) {
// The flag being queried should exist in
@@ -544,7 +600,9 @@ public class ManifestTestListAdapter extends TestListAdapter {
}
private static List<Integer> getHdmiDeviceType()
- throws InvocationTargetException, IllegalAccessException, ClassNotFoundException,
+ throws InvocationTargetException,
+ IllegalAccessException,
+ ClassNotFoundException,
NoSuchMethodException {
Method getStringMethod =
ClassLoader.getSystemClassLoader()
@@ -559,18 +617,22 @@ public class ManifestTestListAdapter extends TestListAdapter {
.collect(Collectors.toList());
}
- private boolean hasBattery(){
- final Intent batteryInfo = mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+ private boolean hasBattery() {
+ final Intent batteryInfo =
+ mContext.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
return batteryInfo.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
}
List<TestListItem> filterTests(List<TestListItem> tests, String mode) {
List<TestListItem> filteredTests = new ArrayList<>();
for (TestListItem test : tests) {
- if (!hasAnyFeature(test.excludedFeatures) && hasAllFeatures(test.requiredFeatures)
+ if (!hasAnyFeature(test.excludedFeatures)
+ && hasAllFeatures(test.requiredFeatures)
&& hasAllActions(test.requiredActions)
- && matchAllConfigs(test.requiredConfigs)
- && matchDisplayMode(test.displayMode, mode)) {
+ && matchAllConfigs(mContext, test.requiredConfigs)
+ && matchDisplayMode(test.displayMode, mode)
+ && macthTestFilter(test.title)
+ && matchSystemPlanStatus(test.testName)) {
if (test.applicableFeatures == null || hasAnyFeature(test.applicableFeatures)) {
// Add suffix in test name if the test is in the folded mode.
test.testName = setTestNameSuffix(mode, test.testName);
@@ -585,39 +647,15 @@ public class ManifestTestListAdapter extends TestListAdapter {
return filteredTests;
}
- @Override
- public int getCount() {
- if (!sInitialLaunch && mTestParent == null) {
- return mDisplayModesTests.getOrDefault(sCurrentDisplayMode, new ArrayList<>()).size();
- }
- return super.getCount();
- }
-
- @Override
- public TestListItem getItem(int position) {
- if (mTestParent == null) {
- return mDisplayModesTests.get(sCurrentDisplayMode).get(position);
- }
- return super.getItem(position);
- }
-
- @Override
- public void loadTestResults() {
- if (mTestParent == null) {
- new RefreshTestResultsTask(true).execute();
- } else {
- super.loadTestResults();
- }
- }
-
@SuppressLint("NewApi")
private boolean isHardwareToggleSupported(final int sensorType) {
boolean isToggleSupported = false;
- SensorPrivacyManager sensorPrivacyManager = mContext.getSystemService(
- SensorPrivacyManager.class);
+ SensorPrivacyManager sensorPrivacyManager =
+ mContext.getSystemService(SensorPrivacyManager.class);
if (sensorPrivacyManager != null) {
- isToggleSupported = sensorPrivacyManager.supportsSensorToggle(
- SensorPrivacyManager.TOGGLE_TYPE_HARDWARE, sensorType);
+ isToggleSupported =
+ sensorPrivacyManager.supportsSensorToggle(
+ SensorPrivacyManager.TOGGLE_TYPE_HARDWARE, sensorType);
}
return isToggleSupported;
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
index f95393a3101..baa19519c26 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/ReportExporter.java
@@ -50,9 +50,7 @@ import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
-/**
- * Background task to generate a report and save it to external storage.
- */
+/** Background task to generate a report and save it to external storage. */
public class ReportExporter extends AsyncTask<Void, Void, String> {
private static final String TAG = ReportExporter.class.getSimpleName();
private static final boolean DEBUG = true;
@@ -65,7 +63,10 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
private static final String LOG_URL = null;
private static final String REFERENCE_URL = null;
private static final String SUITE_NAME_METADATA_KEY = "SuiteName";
- private static final String SUITE_PLAN = "verifier";
+ // Default CTS-V suite_plan shown in test_result.xml.
+ private static final String DEFAULT_SUITE_PLAN = "verifier";
+ // CTS Verifier System suite_plan shown in test_result.xml.
+ private static final String SYSTEM_SUITE_PLAN = "verifier-system";
private static final String SUITE_BUILD = "0";
private static final String ZIP_EXTENSION = ".zip";
private final long START_MS = System.currentTimeMillis();
@@ -88,9 +89,10 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
}
File reportLogFolder =
- new File(Environment.getExternalStorageDirectory().getAbsolutePath()
- + File.separator
- + LOGS_DIRECTORY);
+ new File(
+ Environment.getExternalStorageDirectory().getAbsolutePath()
+ + File.separator
+ + LOGS_DIRECTORY);
copyFilesRecursively(reportLogFolder, tempDir);
}
@@ -104,10 +106,7 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
for (File file : files) {
Path src = Paths.get(file.getAbsolutePath());
- Path dest = Paths.get(
- destFolder.getAbsolutePath()
- + File.separator
- + file.getName());
+ Path dest = Paths.get(destFolder.getAbsolutePath() + File.separator + file.getName());
try {
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
@@ -119,7 +118,6 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
}
}
-
@Override
protected String doInBackground(Void... params) {
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
@@ -148,15 +146,24 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
copyReportFiles(tempDir);
// create a File object for a report ZIP file
- File reportZipFile = new File(
- verifierReportsDir, getReportName(suiteName) + ZIP_EXTENSION);
+ File reportZipFile = new File(verifierReportsDir, getReportName(suiteName) + ZIP_EXTENSION);
try {
// Serialize the report
String versionName = Version.getVersionName(mContext);
- ResultHandler.writeResults(suiteName, versionName, SUITE_PLAN, SUITE_BUILD,
- result, tempDir, START_MS, END_MS, REFERENCE_URL, LOG_URL,
- COMMAND_LINE_ARGS, null);
+ ResultHandler.writeResults(
+ suiteName,
+ versionName,
+ TestListActivity.getIsSystemEnabled() ? SYSTEM_SUITE_PLAN : DEFAULT_SUITE_PLAN,
+ SUITE_BUILD,
+ result,
+ tempDir,
+ START_MS,
+ END_MS,
+ REFERENCE_URL,
+ LOG_URL,
+ COMMAND_LINE_ARGS,
+ null);
// Serialize the screenshots metadata if at least one exists
if (containsScreenshotMetadata(result)) {
@@ -200,8 +207,8 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
Log.d(TAG, "---- saveReportOnInternalStorage(" + reportZipFile.getAbsolutePath() + ")");
}
try {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
- reportZipFile, ParcelFileDescriptor.MODE_READ_ONLY);
+ ParcelFileDescriptor pfd =
+ ParcelFileDescriptor.open(reportZipFile, ParcelFileDescriptor.MODE_READ_ONLY);
InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
File verifierDir = mContext.getDir(REPORT_DIRECTORY, Context.MODE_PRIVATE);
@@ -223,8 +230,7 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
for (String resultFileName : ResultHandler.RESULT_RESOURCES) {
InputStream rawStream = null;
try {
- rawStream = mContext.getAssets().open(
- String.format("report/%s", resultFileName));
+ rawStream = mContext.getAssets().open(String.format("report/%s", resultFileName));
} catch (IOException e) {
LOG.log(Level.WARNING, "Failed to load " + resultFileName + " from assets.");
}
@@ -242,7 +248,8 @@ public class ReportExporter extends AsyncTask<Void, Void, String> {
private String getReportName(String suiteName) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss", Locale.ENGLISH);
String date = dateFormat.format(new Date());
- return String.format("%s-%s-%s-%s-%s-%s",
+ return String.format(
+ "%s-%s-%s-%s-%s-%s",
date, suiteName, Build.MANUFACTURER, Build.PRODUCT, Build.DEVICE, Build.ID);
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
index 9f987a2822e..e3f06ddb2cf 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
@@ -37,6 +37,7 @@ import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.CompoundButton;
+import android.widget.SearchView;
import android.widget.Switch;
import android.widget.Toast;
@@ -52,15 +53,19 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
private static final String TAG = TestListActivity.class.getSimpleName();
// Records the current display mode.
// Default is unfolded mode, and it will be changed when clicking the switch button.
- public static String sCurrentDisplayMode = DisplayMode.UNFOLDED.toString();
- // Flag of launch app to fetch the unfolded/folded tests in main view from AndroidManifest.xml.
- protected static boolean sInitialLaunch;
+ public static volatile String sCurrentDisplayMode = DisplayMode.UNFOLDED.toString();
+
+ // Whether the verifier-system plan is enabled.
+ private static boolean sIsSystemEnabled = false;
+ // Whether the system switch has been toggled.
+ private static boolean sHasSystemToggled = false;
private String[] mRequestedPermissions;
// Enumerates the display modes, including unfolded and folded.
protected enum DisplayMode {
- UNFOLDED, FOLDED;
+ UNFOLDED,
+ FOLDED;
@Override
public String toString() {
@@ -68,10 +73,10 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
}
/**
- * Coverts the mode as suffix with brackets for test name.
+ * Converts the mode as suffix with brackets for test name.
*
- * @return A string containing mode with brackets for folded mode;
- * empty string for unfolded mode.
+ * @return a string containing mode with brackets for folded mode; empty string for unfolded
+ * mode
*/
public String asSuffix() {
if (name().equals(FOLDED.name())) {
@@ -92,21 +97,29 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
try {
PackageManager pm = getPackageManager();
- PackageInfo packageInfo = pm.getPackageInfo(
- getApplicationInfo().packageName, PackageManager.GET_PERMISSIONS);
+ PackageInfo packageInfo =
+ pm.getPackageInfo(
+ getApplicationInfo().packageName, PackageManager.GET_PERMISSIONS);
mRequestedPermissions = packageInfo.requestedPermissions;
if (mRequestedPermissions != null) {
- String[] permissionsToRequest = removeString(mRequestedPermissions,
- Manifest.permission.ACCESS_BACKGROUND_LOCATION);
- permissionsToRequest = Arrays.stream(permissionsToRequest).filter(s -> {
- try {
- return (pm.getPermissionInfo(s, 0).getProtection() & PROTECTION_DANGEROUS)
- != 0;
- } catch (NameNotFoundException e) {
- return false;
- }
- }).toArray(String[]::new);
+ String[] permissionsToRequest =
+ removeString(
+ mRequestedPermissions,
+ Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+ permissionsToRequest =
+ Arrays.stream(permissionsToRequest)
+ .filter(
+ s -> {
+ try {
+ return (pm.getPermissionInfo(s, 0).getProtection()
+ & PROTECTION_DANGEROUS)
+ != 0;
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ })
+ .toArray(String[]::new);
requestPermissions(permissionsToRequest, CTS_VERIFIER_PERMISSION_REQUEST);
}
createContinue();
@@ -116,31 +129,6 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
}
}
- private void createContinue() {
- if (!isTaskRoot()) {
- finish();
- }
- sInitialLaunch = true;
-
- // Restores the last display mode when launching the app after killing the process.
- if (getCurrentDisplayMode().equals(DisplayMode.FOLDED.toString())) {
- sCurrentDisplayMode = DisplayMode.FOLDED.toString();
- }
-
- setTitle(getString(R.string.title_version, Version.getVersionName(this)));
-
- if (!getWindow().hasFeature(Window.FEATURE_ACTION_BAR)) {
- View footer = getLayoutInflater().inflate(R.layout.test_list_footer, null);
-
- footer.findViewById(R.id.clear).setOnClickListener(this);
- footer.findViewById(R.id.export).setOnClickListener(this);
-
- getListView().addFooterView(footer);
- }
-
- setTestListAdapter(new ManifestTestListAdapter(this, null));
- }
-
@Override
public void onRequestPermissionsResult(
int requestCode, String permissions[], int[] grantResults) {
@@ -150,9 +138,10 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
// If we're sending them to settings we don't need to request background location
// since they can just grant in settings.
sendUserToSettings();
- } else if (new ArrayList<>(Arrays.asList(mRequestedPermissions)).contains(
- Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
- requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
+ } else if (new ArrayList<>(Arrays.asList(mRequestedPermissions))
+ .contains(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
+ requestPermissions(
+ new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION},
CTS_VERIFIER_BACKGROUND_LOCATION_PERMISSION_REQUEST);
}
return;
@@ -166,20 +155,6 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
}
}
- private AlertDialog sendUserToSettings() {
- return new AlertDialog.Builder(this)
- .setTitle("Please grant all permissions")
- .setPositiveButton(
- "Ok", (dialog, which) -> {
- if (which == AlertDialog.BUTTON_POSITIVE) {
- startActivity(new Intent(
- Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
- Uri.fromParts("package", getPackageName(), null)));
- }
- })
- .show();
- }
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
@@ -194,18 +169,60 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
boolean isFoldedMode = sCurrentDisplayMode.equals(DisplayMode.FOLDED.toString());
displayModeSwitch.setChecked(isFoldedMode);
- displayModeSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView,
- boolean isChecked) {
- if (isChecked) {
- sCurrentDisplayMode = DisplayMode.FOLDED.toString();
- } else {
- sCurrentDisplayMode = DisplayMode.UNFOLDED.toString();
- }
- handleSwitchItemSelected();
- }
- });
+ displayModeSwitch.setOnCheckedChangeListener(
+ new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ sCurrentDisplayMode = DisplayMode.FOLDED.toString();
+ } else {
+ sCurrentDisplayMode = DisplayMode.UNFOLDED.toString();
+ }
+ handleSwitchItemSelected();
+ }
+ });
+
+ // Switch button for verifier-system plan.
+ item = (MenuItem) menu.findItem(R.id.system_switch_item);
+ item.setActionView(R.layout.system_switch);
+ final Switch systemSwitch = item.getActionView().findViewById(R.id.switch_button);
+
+ systemSwitch.setChecked(sIsSystemEnabled);
+ systemSwitch.setOnCheckedChangeListener(
+ new CompoundButton.OnCheckedChangeListener() {
+
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (!sHasSystemToggled && isChecked) {
+ sHasSystemToggled = true;
+ notifyUserSystemPlan(systemSwitch);
+ } else {
+ updateIsSystemEnabled(isChecked);
+ }
+ }
+ });
+
+ SearchView searchView = (SearchView) menu.findItem(R.id.search_test).getActionView();
+ searchView.setOnQueryTextListener(
+ new SearchView.OnQueryTextListener() {
+
+ public boolean onQueryTextSubmit(String query) {
+ Log.i(TAG, "Got submitted query: " + query);
+ handleQueryUpdated(query);
+ return true;
+ }
+
+ public boolean onQueryTextChange(String newText) {
+ if (newText == null || newText.isEmpty()) {
+ Log.i(TAG, "Clear filter");
+ handleQueryUpdated(newText);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ });
+
return true;
}
@@ -214,17 +231,141 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
return handleMenuItemSelected(item.getItemId()) ? true : super.onOptionsItemSelected(item);
}
+ /** Gets the verifier-system plan enabled status. */
+ static boolean getIsSystemEnabled() {
+ return sIsSystemEnabled;
+ }
+
+ /** Checks if a list of int array contains a given int value. */
+ private static boolean arrayContains(int[] array, int value) {
+ if (array == null) {
+ return false;
+ }
+ for (int element : array) {
+ if (element == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /** Removes the first occurrence of a string from a given string array. */
+ private static String[] removeString(String[] cur, String val) {
+ if (cur == null) {
+ return null;
+ }
+ final int n = cur.length;
+ for (int i = 0; i < n; i++) {
+ if (Objects.equals(cur[i], val)) {
+ String[] ret = new String[n - 1];
+ if (i > 0) {
+ System.arraycopy(cur, 0, ret, 0, i);
+ }
+ if (i < (n - 1)) {
+ System.arraycopy(cur, i + 1, ret, i, n - i - 1);
+ }
+ return ret;
+ }
+ }
+ return cur;
+ }
+
+ private void createContinue() {
+ if (!isTaskRoot()) {
+ finish();
+ }
+
+ // Restores the last display mode when launching the app after killing the process.
+ if (getCurrentDisplayMode().equals(DisplayMode.FOLDED.toString())) {
+ sCurrentDisplayMode = DisplayMode.FOLDED.toString();
+ }
+
+ setTitle(getString(R.string.title_version, Version.getVersionName(this)));
+
+ if (!getWindow().hasFeature(Window.FEATURE_ACTION_BAR)) {
+ View footer = getLayoutInflater().inflate(R.layout.test_list_footer, null);
+
+ footer.findViewById(R.id.clear).setOnClickListener(this);
+ footer.findViewById(R.id.export).setOnClickListener(this);
+
+ getListView().addFooterView(footer);
+ }
+
+ setTestListAdapter(
+ new ManifestTestListAdapter(/* context= */ this, /* testParent= */ null));
+ }
+
+ private AlertDialog sendUserToSettings() {
+ return new AlertDialog.Builder(this)
+ .setTitle("Please grant all permissions")
+ .setPositiveButton(
+ "Ok",
+ (dialog, which) -> {
+ if (which == AlertDialog.BUTTON_POSITIVE) {
+ startActivity(
+ new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ .setData(
+ Uri.fromParts(
+ "package",
+ getPackageName(),
+ null)));
+ }
+ })
+ .show();
+ }
+
+ /** Notifies the user about the verifier-system plan. */
+ private AlertDialog notifyUserSystemPlan(Switch systemSwitch) {
+ return new AlertDialog.Builder(this)
+ .setTitle("Verifier System Plan")
+ .setMessage(
+ "This is a feature to execute verifier tests for the system layer"
+ + " partitions. Click \"Yes\" to proceed or \"No\" to run all of the"
+ + " verifier tests.")
+ .setPositiveButton(
+ "Yes",
+ new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int whichButton) {
+ updateIsSystemEnabled(true);
+ }
+ })
+ .setNegativeButton(
+ "No",
+ new DialogInterface.OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int whichButton) {
+ systemSwitch.setChecked(false);
+ }
+ })
+ .show();
+ }
+
+ /** Updates the verifier-system plan enabled status and refreshes the test list. */
+ private void updateIsSystemEnabled(boolean isChecked) {
+ Log.i(TAG, "verifier-system plan enabled: " + isChecked);
+ sIsSystemEnabled = isChecked;
+ handleSwitchItemSelected();
+ }
+
+ /** Sets up the flags after switching display mode and reloads tests on UI. */
+ private void handleSwitchItemSelected() {
+ setCurrentDisplayMode(sCurrentDisplayMode);
+ mAdapter.loadTestResults();
+ }
+
private void handleClearItemSelected() {
new AlertDialog.Builder(this)
.setMessage(R.string.test_results_clear_title)
- .setPositiveButton(R.string.test_results_clear_yes,
+ .setPositiveButton(
+ R.string.test_results_clear_yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mAdapter.clearTestResults();
Toast.makeText(
- TestListActivity.this,
- R.string.test_results_cleared,
- Toast.LENGTH_SHORT)
+ TestListActivity.this,
+ R.string.test_results_cleared,
+ Toast.LENGTH_SHORT)
.show();
}
})
@@ -236,12 +377,6 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
new ReportExporter(this, mAdapter).execute();
}
- // Sets up the flags after switching display mode and reloads tests on UI.
- private void handleSwitchItemSelected() {
- setCurrentDisplayMode(sCurrentDisplayMode);
- mAdapter.loadTestResults();
- }
-
private boolean handleMenuItemSelected(int id) {
if (id == R.id.clear) {
handleClearItemSelected();
@@ -254,10 +389,21 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
return true;
}
+ /** Triggered when a new query is input. */
+ private void handleQueryUpdated(String query) {
+ if (query != null && !query.isEmpty()) {
+ mAdapter.setTestFilter(query);
+ } else {
+ // Reset the filter as null to show all tests.
+ mAdapter.setTestFilter(/* testFilter= */ null);
+ }
+ mAdapter.loadTestResults();
+ }
+
/**
* Sets current display mode to sharedpreferences.
*
- * @param mode A string of current display mode.
+ * @param mode a string of current display mode
*/
private void setCurrentDisplayMode(String mode) {
SharedPreferences pref = getSharedPreferences(DisplayMode.class.getName(), MODE_PRIVATE);
@@ -267,41 +413,12 @@ public class TestListActivity extends AbstractTestListActivity implements View.O
/**
* Gets current display mode from sharedpreferences.
*
- * @return A string of current display mode.
+ * @return a string of current display mode
*/
private String getCurrentDisplayMode() {
- String mode = getSharedPreferences(DisplayMode.class.getName(), MODE_PRIVATE)
- .getString(DisplayMode.class.getName(), "");
+ String mode =
+ getSharedPreferences(DisplayMode.class.getName(), MODE_PRIVATE)
+ .getString(DisplayMode.class.getName(), "");
return mode;
}
-
- private static boolean arrayContains(int[] array, int value) {
- if (array == null) return false;
- for (int element : array) {
- if (element == value) {
- return true;
- }
- }
- return false;
- }
-
- private static String[] removeString(String[] cur, String val) {
- if (cur == null) {
- return null;
- }
- final int n = cur.length;
- for (int i = 0; i < n; i++) {
- if (Objects.equals(cur[i], val)) {
- String[] ret = new String[n - 1];
- if (i > 0) {
- System.arraycopy(cur, 0, ret, 0, i);
- }
- if (i < (n - 1)) {
- System.arraycopy(cur, i + 1, ret, i, n - i - 1);
- }
- return ret;
- }
- }
- return cur;
- }
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index de692d7f429..418e957bef9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -18,7 +18,6 @@ package com.android.cts.verifier;
import static com.android.cts.verifier.ReportExporter.LOGS_DIRECTORY;
import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
-import static com.android.cts.verifier.TestListActivity.sInitialLaunch;
import android.content.ContentResolver;
import android.content.Context;
@@ -50,9 +49,8 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
/**
- * {@link BaseAdapter} that handles loading, refreshing, and setting test
- * results. What tests are shown can be customized by overriding
- * {@link #getRows()}. See {@link ArrayTestListAdapter} and
+ * {@link BaseAdapter} that handles loading, refreshing, and setting test results. What tests are
+ * shown can be customized by overriding {@link #getRows()}. See {@link ArrayTestListAdapter} and
* {@link ManifestTestListAdapter} for examples.
*/
public abstract class TestListAdapter extends BaseAdapter {
@@ -94,11 +92,15 @@ public abstract class TestListAdapter extends BaseAdapter {
private final LayoutInflater mLayoutInflater;
- /** Map from display mode to the list of {@link TestListItem}.
- * Records the TestListItem from main view only, including unfolded mode and folded mode
- * respectively. */
+ /**
+ * Map from display mode to the list of {@link TestListItem}. Records the TestListItem from main
+ * view only, including unfolded mode and folded mode respectively.
+ */
protected Map<String, List<TestListItem>> mDisplayModesTests = new HashMap<>();
+ /** A keyword to help filter out test cases by the test name. */
+ protected String mTestFilter;
+
/** {@link ListView} row that is either a test category header or a test. */
public static class TestListItem {
@@ -131,59 +133,167 @@ public abstract class TestListAdapter extends BaseAdapter {
// TODO: refactor to use a Builder approach instead
- public static TestListItem newTest(Context context, int titleResId, String testName,
- Intent intent, String[] requiredFeatures, String[] excludedFeatures,
- String[] applicableFeatures) {
- return newTest(context.getString(titleResId), testName, intent, requiredFeatures,
- excludedFeatures, applicableFeatures);
- }
-
- public static TestListItem newTest(Context context, int titleResId, String testName,
- Intent intent, String[] requiredFeatures, String[] excludedFeatures) {
- return newTest(context.getString(titleResId), testName, intent, requiredFeatures,
- excludedFeatures, /* applicableFeatures= */ null);
- }
-
- public static TestListItem newTest(Context context, int titleResId, String testName,
- Intent intent, String[] requiredFeatures) {
- return newTest(context.getString(titleResId), testName, intent, requiredFeatures,
- /* excludedFeatures= */ null, /* applicableFeatures= */ null);
- }
-
- public static TestListItem newTest(String title, String testName, Intent intent,
- String[] requiredFeatures, String[] requiredConfigs, String[] requiredActions,
- String[] excludedFeatures, String[] applicableFeatures, String displayMode) {
- return new TestListItem(title, testName, intent, requiredFeatures, requiredConfigs,
- requiredActions, excludedFeatures, applicableFeatures, displayMode);
- }
-
- public static TestListItem newTest(String title, String testName, Intent intent,
- String[] requiredFeatures, String[] requiredConfigs, String[] excludedFeatures,
- String[] applicableFeatures) {
- return new TestListItem(title, testName, intent, requiredFeatures, requiredConfigs,
- /* requiredActions = */ null, excludedFeatures, applicableFeatures,
+ /**
+ * Creates a new test item with given required, excluded and applicable features, the
+ * context and the resource ID of the title.
+ */
+ public static TestListItem newTest(
+ Context context,
+ int titleResId,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] excludedFeatures,
+ String[] applicableFeatures) {
+ return newTest(
+ context.getString(titleResId),
+ testName,
+ intent,
+ requiredFeatures,
+ excludedFeatures,
+ applicableFeatures);
+ }
+
+ /**
+ * Creates a new test item with given required and excluded features, the context and the
+ * resource ID of the title.
+ */
+ public static TestListItem newTest(
+ Context context,
+ int titleResId,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] excludedFeatures) {
+ return newTest(
+ context.getString(titleResId),
+ testName,
+ intent,
+ requiredFeatures,
+ excludedFeatures,
+ /* applicableFeatures= */ null);
+ }
+
+ /**
+ * Creates a new test item with given required features, the context and the resource ID of
+ * the title.
+ */
+ public static TestListItem newTest(
+ Context context,
+ int titleResId,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures) {
+ return newTest(
+ context.getString(titleResId),
+ testName,
+ intent,
+ requiredFeatures,
+ /* excludedFeatures= */ null,
+ /* applicableFeatures= */ null);
+ }
+
+ /**
+ * Creates a new test item with given display mode, the required, excluded, applicable
+ * features and required configurations and actions.
+ */
+ public static TestListItem newTest(
+ String title,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] requiredConfigs,
+ String[] requiredActions,
+ String[] excludedFeatures,
+ String[] applicableFeatures,
+ String displayMode) {
+ return new TestListItem(
+ title,
+ testName,
+ intent,
+ requiredFeatures,
+ requiredConfigs,
+ requiredActions,
+ excludedFeatures,
+ applicableFeatures,
+ displayMode);
+ }
+
+ /**
+ * Creates a new test item with given required, excluded, applicable features and required
+ * configurations.
+ */
+ public static TestListItem newTest(
+ String title,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] requiredConfigs,
+ String[] excludedFeatures,
+ String[] applicableFeatures) {
+ return new TestListItem(
+ title,
+ testName,
+ intent,
+ requiredFeatures,
+ requiredConfigs,
+ /* requiredActions= */ null,
+ excludedFeatures,
+ applicableFeatures,
/* displayMode= */ null);
}
- public static TestListItem newTest(String title, String testName, Intent intent,
- String[] requiredFeatures, String[] excludedFeatures, String[] applicableFeatures) {
- return new TestListItem(title, testName, intent, requiredFeatures,
- /* requiredConfigs= */ null, /* requiredActions = */ null, excludedFeatures,
- applicableFeatures, /* displayMode= */ null);
+ /** Creates a new test item with given required, excluded and applicable features. */
+ public static TestListItem newTest(
+ String title,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] excludedFeatures,
+ String[] applicableFeatures) {
+ return new TestListItem(
+ title,
+ testName,
+ intent,
+ requiredFeatures,
+ /* requiredConfigs= */ null,
+ /* requiredActions= */ null,
+ excludedFeatures,
+ applicableFeatures,
+ /* displayMode= */ null);
}
- public static TestListItem newTest(String title, String testName, Intent intent,
- String[] requiredFeatures, String[] excludedFeatures) {
- return new TestListItem(title, testName, intent, requiredFeatures,
- /* requiredConfigs= */ null, /* requiredActions = */ null, excludedFeatures,
- /* applicableFeatures= */ null, /* displayMode= */ null);
+ /** Creates a new test item with given required and excluded features. */
+ public static TestListItem newTest(
+ String title,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] excludedFeatures) {
+ return new TestListItem(
+ title,
+ testName,
+ intent,
+ requiredFeatures,
+ /* requiredConfigs= */ null,
+ /* requiredActions= */ null,
+ excludedFeatures,
+ /* applicableFeatures= */ null,
+ /* displayMode= */ null);
}
- public static TestListItem newTest(String title, String testName, Intent intent,
- String[] requiredFeatures) {
- return new TestListItem(title, testName, intent, requiredFeatures,
- /* requiredConfigs= */ null, /* requiredActions = */ null,
- /* excludedFeatures= */ null, /* applicableFeatures= */ null,
+ /** Creates a new test item with given required features. */
+ public static TestListItem newTest(
+ String title, String testName, Intent intent, String[] requiredFeatures) {
+ return new TestListItem(
+ title,
+ testName,
+ intent,
+ requiredFeatures,
+ /* requiredConfigs= */ null,
+ /* requiredActions= */ null,
+ /* excludedFeatures= */ null,
+ /* applicableFeatures= */ null,
/* displayMode= */ null);
}
@@ -192,27 +302,49 @@ public abstract class TestListAdapter extends BaseAdapter {
}
public static TestListItem newCategory(String title) {
- return new TestListItem(title, /* testName= */ null, /* intent= */ null,
- /* requiredFeatures= */ null, /* requiredConfigs= */ null,
- /* requiredActions = */ null, /* excludedFeatures= */ null,
- /* applicableFeatures= */ null, /* displayMode= */ null);
+ return new TestListItem(
+ title,
+ /* testName= */ null,
+ /* intent= */ null,
+ /* requiredFeatures= */ null,
+ /* requiredConfigs= */ null,
+ /* requiredActions= */ null,
+ /* excludedFeatures= */ null,
+ /* applicableFeatures= */ null,
+ /* displayMode= */ null);
}
- protected TestListItem(String title, String testName, Intent intent,
- String[] requiredFeatures, String[] excludedFeatures, String[] applicableFeatures) {
- this(title, testName, intent, requiredFeatures, /* requiredConfigs= */ null,
- /* requiredActions = */ null, excludedFeatures, applicableFeatures,
+ protected TestListItem(
+ String title,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] excludedFeatures,
+ String[] applicableFeatures) {
+ this(
+ title,
+ testName,
+ intent,
+ requiredFeatures,
+ /* requiredConfigs= */ null,
+ /* requiredActions= */ null,
+ excludedFeatures,
+ applicableFeatures,
/* displayMode= */ null);
}
- protected TestListItem(String title, String testName, Intent intent,
- String[] requiredFeatures, String[] requiredConfigs, String[] requiredActions,
- String[] excludedFeatures, String[] applicableFeatures, String displayMode) {
+ protected TestListItem(
+ String title,
+ String testName,
+ Intent intent,
+ String[] requiredFeatures,
+ String[] requiredConfigs,
+ String[] requiredActions,
+ String[] excludedFeatures,
+ String[] applicableFeatures,
+ String displayMode) {
this.title = title;
- if (!sInitialLaunch) {
- testName = setTestNameSuffix(sCurrentDisplayMode, testName);
- }
- this.testName = testName;
+ this.testName = setTestNameSuffix(sCurrentDisplayMode, testName);
this.intent = intent;
this.requiredActions = requiredActions;
this.requiredFeatures = requiredFeatures;
@@ -234,11 +366,12 @@ public abstract class TestListAdapter extends BaseAdapter {
TestResultContentObserver observer = new TestResultContentObserver();
ContentResolver resolver = context.getContentResolver();
- resolver.registerContentObserver(TestResultsProvider.getResultContentUri(context), true, observer);
+ resolver.registerContentObserver(
+ TestResultsProvider.getResultContentUri(context), true, observer);
}
public void loadTestResults() {
- new RefreshTestResultsTask(false).execute();
+ new RefreshTestResultsTask().execute();
}
public void clearTestResults() {
@@ -252,33 +385,25 @@ public abstract class TestListAdapter extends BaseAdapter {
TestResultHistoryCollection histories = testResult.getHistoryCollection();
histories.merge(null, mHistories.get(name));
- new SetTestResultTask(name, testResult.getResult(),
- testResult.getDetails(), testResult.getReportLog(), histories,
- mScreenshotsMetadata.get(name)).execute();
+ new SetTestResultTask(
+ name,
+ testResult.getResult(),
+ testResult.getDetails(),
+ testResult.getReportLog(),
+ histories,
+ mScreenshotsMetadata.get(name))
+ .execute();
}
- class RefreshTestResultsTask extends AsyncTask<Void, Void, RefreshResult> {
-
- private boolean mIsFromMainView;
+ void setTestFilter(String testFilter) {
+ mTestFilter = testFilter;
+ }
- RefreshTestResultsTask(boolean isFromMainView) {
- mIsFromMainView = isFromMainView;
- }
+ class RefreshTestResultsTask extends AsyncTask<Void, Void, RefreshResult> {
@Override
protected RefreshResult doInBackground(Void... params) {
- List<TestListItem> rows = getRows();
- // When initial launch, needs to fetch tests in the unfolded/folded mode
- // to be stored in mDisplayModesTests as the basis for the future switch.
- if (sInitialLaunch) {
- sInitialLaunch = false;
- }
-
- if (mIsFromMainView) {
- rows = mDisplayModesTests.get(sCurrentDisplayMode);
- }
-
- return getRefreshResults(rows);
+ return getRefreshResults(getRows());
}
@Override
@@ -346,8 +471,13 @@ public abstract class TestListAdapter extends BaseAdapter {
ContentResolver resolver = mContext.getContentResolver();
Cursor cursor = null;
try {
- cursor = resolver.query(TestResultsProvider.getResultContentUri(mContext), REFRESH_PROJECTION,
- null, null, null);
+ cursor =
+ resolver.query(
+ TestResultsProvider.getResultContentUri(mContext),
+ REFRESH_PROJECTION,
+ null,
+ null,
+ null);
if (cursor.moveToFirst()) {
do {
String testName = cursor.getString(1);
@@ -355,7 +485,7 @@ public abstract class TestListAdapter extends BaseAdapter {
String testDetails = cursor.getString(3);
ReportLog reportLog = (ReportLog) deserialize(cursor.getBlob(4));
TestResultHistoryCollection historyCollection =
- (TestResultHistoryCollection) deserialize(cursor.getBlob(5));
+ (TestResultHistoryCollection) deserialize(cursor.getBlob(5));
TestScreenshotsMetadata screenshots =
(TestScreenshotsMetadata) deserialize(cursor.getBlob(6));
results.put(testName, testResult);
@@ -392,9 +522,11 @@ public abstract class TestListAdapter extends BaseAdapter {
// Apart from deleting metadata from content resolver database, need to delete
// files generated in LOGS_DIRECTORY. For example screenshots.
- File resFolder = new File(
- Environment.getExternalStorageDirectory().getAbsolutePath()
- + File.separator + LOGS_DIRECTORY);
+ File resFolder =
+ new File(
+ Environment.getExternalStorageDirectory().getAbsolutePath()
+ + File.separator
+ + LOGS_DIRECTORY);
deleteDirectory(resFolder);
return null;
@@ -433,12 +565,13 @@ public abstract class TestListAdapter extends BaseAdapter {
// Loads history from ContentProvider directly if it has not been loaded yet.
ContentResolver resolver = mContext.getContentResolver();
- try (Cursor cursor = resolver.query(
- TestResultsProvider.getTestNameUri(mContext, mTestName),
- new String[] {TestResultsProvider.COLUMN_TEST_RESULT_HISTORY},
- null,
- null,
- null)) {
+ try (Cursor cursor =
+ resolver.query(
+ TestResultsProvider.getTestNameUri(mContext, mTestName),
+ new String[] {TestResultsProvider.COLUMN_TEST_RESULT_HISTORY},
+ null,
+ null,
+ null)) {
if (cursor.moveToFirst()) {
do {
TestResultHistoryCollection historyCollection =
@@ -449,7 +582,12 @@ public abstract class TestListAdapter extends BaseAdapter {
}
}
TestResultsProvider.setTestResult(
- mContext, mTestName, mResult, mDetails, mReportLog, mHistoryCollection,
+ mContext,
+ mTestName,
+ mResult,
+ mDetails,
+ mReportLog,
+ mHistoryCollection,
mScreenshotsMetadata);
return null;
}
@@ -507,6 +645,16 @@ public abstract class TestListAdapter extends BaseAdapter {
return position;
}
+ /** Gets {@link TestListItem} with the given test name. */
+ public TestListItem getItemByName(String testName) {
+ for (TestListItem item : mRows) {
+ if (item != null && item.testName != null && item.testName.equals(testName)) {
+ return item;
+ }
+ }
+ return null;
+ }
+
public int getTestResult(int position) {
TestListItem item = getItem(position);
return mTestResults.containsKey(item.testName)
@@ -516,23 +664,20 @@ public abstract class TestListAdapter extends BaseAdapter {
public String getTestDetails(int position) {
TestListItem item = getItem(position);
- return mTestDetails.containsKey(item.testName)
- ? mTestDetails.get(item.testName)
- : null;
+ return mTestDetails.containsKey(item.testName) ? mTestDetails.get(item.testName) : null;
}
public ReportLog getReportLog(int position) {
TestListItem item = getItem(position);
- return mReportLogs.containsKey(item.testName)
- ? mReportLogs.get(item.testName)
- : null;
+ return mReportLogs.containsKey(item.testName) ? mReportLogs.get(item.testName) : null;
}
/**
- * Get test result histories.
+ * Gets test result histories.
*
- * @param position The position of test.
- * @return A {@link TestResultHistoryCollection} object containing test result histories of tests.
+ * @param position the position of test
+ * @return a {@link TestResultHistoryCollection} object containing test result histories of
+ * tests
*/
public TestResultHistoryCollection getHistoryCollection(int position) {
TestListItem item = getItem(position);
@@ -543,10 +688,10 @@ public abstract class TestListAdapter extends BaseAdapter {
}
/**
- * Get test screenshots metadata
+ * Gets test screenshots metadata.
*
- * @param position The position of test
- * @return A {@link TestScreenshotsMetadata} object containing test screenshots metadata.
+ * @param position the position of test
+ * @return a {@link TestScreenshotsMetadata} object containing test screenshots metadata
*/
public TestScreenshotsMetadata getScreenshotsMetadata(String mode, int position) {
TestListItem item = getItem(mode, position);
@@ -556,86 +701,81 @@ public abstract class TestListAdapter extends BaseAdapter {
}
/**
- * Get test item by the given display mode and position.
+ * Gets test item by the given display mode and position.
*
- * @param mode The display mode.
- * @param position The position of test.
- * @return A {@link TestListItem} object containing the test item.
+ * @param mode the display mode
+ * @param position the position of test
+ * @return a {@link TestListItem} object containing the test item
*/
public TestListItem getItem(String mode, int position) {
return mDisplayModesTests.get(mode).get(position);
}
/**
- * Get test item count by the given display mode.
+ * Gets test item count by the given display mode.
*
- * @param mode The display mode.
- * @return A count of test items.
+ * @param mode the display mode
+ * @return a count of test items
*/
- public int getCount(String mode){
+ public int getCount(String mode) {
return mDisplayModesTests.getOrDefault(mode, new ArrayList<>()).size();
}
/**
- * Get test result by the given display mode and position.
+ * Gets test result by the given display mode and position.
*
- * @param mode The display mode.
- * @param position The position of test.
- * @return The test item result.
+ * @param mode the display mode
+ * @param position the position of test
+ * @return the test item result
*/
public int getTestResult(String mode, int position) {
TestListItem item = mDisplayModesTests.get(mode).get(position);
return mTestResults.containsKey(item.testName)
- ? mTestResults.get(item.testName)
- : TestResult.TEST_RESULT_NOT_EXECUTED;
+ ? mTestResults.get(item.testName)
+ : TestResult.TEST_RESULT_NOT_EXECUTED;
}
/**
- * Get test details by the given display mode and position.
+ * Gets test details by the given display mode and position.
*
- * @param mode The display mode.
- * @param position The position of test.
- * @return A string containing the test details.
+ * @param mode the display mode
+ * @param position the position of test
+ * @return a string containing the test details
*/
public String getTestDetails(String mode, int position) {
TestListItem item = mDisplayModesTests.get(mode).get(position);
- return mTestDetails.containsKey(item.testName)
- ? mTestDetails.get(item.testName)
- : null;
+ return mTestDetails.containsKey(item.testName) ? mTestDetails.get(item.testName) : null;
}
/**
- * Get test report log by the given display mode and position.
+ * Gets test report log by the given display mode and position.
*
- * @param mode The display mode.
- * @param position The position of test.
- * @return A {@link ReportLog} object containing the test report log of the test item.
+ * @param mode the display mode
+ * @param position the position of test
+ * @return a {@link ReportLog} object containing the test report log of the test item
*/
public ReportLog getReportLog(String mode, int position) {
TestListItem item = mDisplayModesTests.get(mode).get(position);
- return mReportLogs.containsKey(item.testName)
- ? mReportLogs.get(item.testName)
- : null;
+ return mReportLogs.containsKey(item.testName) ? mReportLogs.get(item.testName) : null;
}
/**
- * Get test result histories by the given display mode and position.
+ * Gets test result histories by the given display mode and position.
*
- * @param mode The display mode.
- * @param position The position of test.
- * @return A {@link TestResultHistoryCollection} object containing the test result histories of
- * the test item.
+ * @param mode the display mode
+ * @param position the position of test
+ * @return a {@link TestResultHistoryCollection} object containing the test result histories of
+ * the test item
*/
public TestResultHistoryCollection getHistoryCollection(String mode, int position) {
TestListItem item = mDisplayModesTests.get(mode).get(position);
- return mHistories.containsKey(item.testName)
- ? mHistories.get(item.testName)
- : null;
+ return mHistories.containsKey(item.testName) ? mHistories.get(item.testName) : null;
}
public boolean allTestsPassed() {
for (TestListItem item : mRows) {
- if (item != null && item.isTest()
+ if (item != null
+ && item.isTest()
&& (!mTestResults.containsKey(item.testName)
|| (mTestResults.get(item.testName)
!= TestResult.TEST_RESULT_PASSED))) {
@@ -700,7 +840,6 @@ public abstract class TestListAdapter extends BaseAdapter {
return android.R.layout.simple_list_item_1;
default:
throw new IllegalArgumentException("Illegal view type: " + viewType);
-
}
}
@@ -735,12 +874,13 @@ public abstract class TestListAdapter extends BaseAdapter {
*
* @param mode A string of current display mode.
* @param name A string of test name.
- * @return A string of test name with suffix, [folded], in the folded mode.
- * A string of input test name in the unfolded mode.
+ * @return A string of test name with suffix, [folded], in the folded mode. A string of input
+ * test name in the unfolded mode.
*/
public static String setTestNameSuffix(String mode, String name) {
- if (name != null && mode.equals(DisplayMode.FOLDED.toString())
- && !name.endsWith(DisplayMode.FOLDED.asSuffix())){
+ if (name != null
+ && mode.equals(DisplayMode.FOLDED.toString())
+ && !name.endsWith(DisplayMode.FOLDED.asSuffix())) {
return name + DisplayMode.FOLDED.asSuffix();
}
return name;