diff options
author | kgui <kgui@google.com> | 2023-11-14 16:48:47 +0800 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-01-29 23:39:54 +0000 |
commit | 0bdb70db6eb089b27d05ef1110b5dacc4a502836 (patch) | |
tree | a80b3e0ffa8cc1b552686cb3260e5f5ffa49cd02 | |
parent | 8346ee5c6c6239868f893cdb72080e55843d7904 (diff) | |
download | cts-0bdb70db6eb089b27d05ef1110b5dacc4a502836.tar.gz |
Support a "System" toggle in CTS-Verifier. When it's enabled:
1. camera ITS test (both folded and unfolded) is filtered to be shown in the list.
2. the test_result.xml has the "verify-system" as the suite_plan's value.
More demos are in b/301678868.
Bug: 301678868
Test: local built CTS-V
(cherry picked from https://android-review.googlesource.com/q/commit:9ef42944abc073b3c69757ebdab26e559e6008f6)
Merged-In: Ic9c945a10e50f27de6c71716ff134bf68fdee359
Change-Id: Ic9c945a10e50f27de6c71716ff134bf68fdee359
6 files changed, 246 insertions, 107 deletions
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 95bfd5877e9..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" diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml index 790f06bf502..f9347120514 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> @@ -36,6 +37,9 @@ <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/src/com/android/cts/verifier/ManifestTestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java index a6d536aeecc..e0c94ae4562 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/ManifestTestListAdapter.java @@ -186,6 +186,13 @@ public class ManifestTestListAdapter extends TestListAdapter { */ 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; @@ -223,8 +230,9 @@ public class ManifestTestListAdapter extends TestListAdapter { } } - if (mTestFilter != null) { - // Filter test rows dynamically when the filter is specified. + 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( @@ -607,6 +615,20 @@ public class ManifestTestListAdapter extends TestListAdapter { .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 boolean isVisibleBackgroundNonProfileUser() { if (!SdkLevel.isAtLeastU()) { Log.d(LOG_TAG, "isVisibleBagroundNonProfileUser() returning false on pre-UDC device"); @@ -660,7 +682,8 @@ public class ManifestTestListAdapter extends TestListAdapter { && matchAllConfigs(mContext, test.requiredConfigs) && matchDisplayMode(test.displayMode, mode) && !matchAnyExcludedUserType(test.excludedUserTypes) - && macthTestFilter(test.title)) { + && 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); 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 790bf73e956..e3f06ddb2cf 100644 --- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java +++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java @@ -55,6 +55,11 @@ public class TestListActivity extends AbstractTestListActivity implements View.O // Default is unfolded mode, and it will be changed when clicking the switch button. 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. @@ -124,31 +129,6 @@ public class TestListActivity extends AbstractTestListActivity implements View.O } } - 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)); - } - @Override public void onRequestPermissionsResult( int requestCode, String permissions[], int[] grantResults) { @@ -175,25 +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(); @@ -221,6 +182,26 @@ public class TestListActivity extends AbstractTestListActivity implements View.O } }); + // 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() { @@ -250,6 +231,129 @@ 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) @@ -273,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(); @@ -323,34 +421,4 @@ public class TestListActivity extends AbstractTestListActivity implements View.O .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; - } } |