Merge "Add wait time after broadcasting <Active Source> from adapter" into android12-tests-dev
diff --git a/apps/CameraITS/tests/scene1_1/test_black_white.py b/apps/CameraITS/tests/scene1_1/test_black_white.py
index 2421cc9..8a72b1a 100644
--- a/apps/CameraITS/tests/scene1_1/test_black_white.py
+++ b/apps/CameraITS/tests/scene1_1/test_black_white.py
@@ -29,6 +29,7 @@
import image_processing_utils
import its_session_utils
+_ANDROID10_API_LEVEL = 29
CH_FULL_SCALE = 255
CH_THRESH_BLACK = 6
CH_THRESH_WHITE = CH_FULL_SCALE - 6
@@ -148,10 +149,12 @@
assert mean > CH_THRESH_WHITE, e_msg
# Assert channels saturate evenly (was test_channel_saturation)
- e_msg = 'ch saturation not equal! RGB: %s, ATOL: %.f' % (
- str(white_means), CH_TOL_WHITE)
- assert np.isclose(
- np.amin(white_means), np.amax(white_means), atol=CH_TOL_WHITE), e_msg
+ first_api_level = its_session_utils.get_first_api_level(self.dut.serial)
+ if first_api_level >= _ANDROID10_API_LEVEL:
+ e_msg = 'ch saturation not equal! RGB: %s, ATOL: %.f' % (
+ str(white_means), CH_TOL_WHITE)
+ assert np.isclose(
+ np.amin(white_means), np.amax(white_means), atol=CH_TOL_WHITE), e_msg
if __name__ == '__main__':
test_runner.main()
diff --git a/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml b/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
index 18eef3e..b40c71d 100644
--- a/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
+++ b/apps/CtsVerifier/res/drawable/display_cutout_test_button.xml
@@ -27,6 +27,16 @@
<corners android:radius="4dp" />
</shape>
</item>
+ <item android:state_focused="true">
+ <shape>
+ <solid android:color="#ffbfbfbf" />
+ <padding android:left="4dp"
+ android:top="4dp"
+ android:right="4dp"
+ android:bottom="4dp" />
+ <corners android:radius="4dp" />
+ </shape>
+ </item>
<item>
<shape>
<solid android:color="#ff7f7f7f" />
diff --git a/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml b/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
index 16943c9..9ea6b35 100644
--- a/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
+++ b/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
@@ -50,6 +50,12 @@
android:layout_height="wrap_content"
android:id="@+id/audio_routingnotification_audioRecord_change"/>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="20sp"
+ android:id="@+id/audio_routingnotification_testresult"/>
+
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -58,13 +64,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/audio_routingnotification_recordBtn"
- android:text="@string/audio_routingnotification_recBtn"/>
+ android:text="@string/audio_general_record"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/audio_routingnotification_recordStopBtn"
- android:text="@string/audio_routingnotification_recStopBtn"/>
+ android:text="@string/audio_general_stop"/>
</LinearLayout>
</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml b/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
index 1cdb131..49eb3cb 100644
--- a/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
+++ b/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
@@ -50,6 +50,12 @@
android:layout_height="wrap_content"
android:id="@+id/audio_routingnotification_audioTrack_change"/>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="20sp"
+ android:id="@+id/audio_routingnotification_testresult"/>
+
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -58,13 +64,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/audio_routingnotification_playBtn"
- android:text="@string/audio_routingnotification_playBtn"/>
+ android:text="@string/audio_general_play"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/audio_routingnotification_playStopBtn"
- android:text="@string/audio_routingnotification_playStopBtn"/>
+ android:text="@string/audio_general_stop"/>
</LinearLayout>
</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index a4b5ce7..ccf64fc 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -4919,24 +4919,36 @@
<!--- AudioInputRoutingNotificationsActivity -->
<string name="audio_input_routingnotifications_test">Audio Input Routing Notifications Test</string>
<string name="audio_input_routingnotification_instructions">
- Click on the "Record" button in the AudioRecord Routing Notifications section below to
- start recording. Insert a wired headset or microphone. Observe a message acknowledging the
- rerouting event below. Remove the wired headset and observe the new routing message.
- Click on the "Stop" button to stop recording.\n
+ Test whether appropriate routing notifications are sent when audio input peripherals are
+ connected to the device.
+ \n\nTest Setup:
+ \nDisconnect any wired audio peripherals.
+ \n\nTest Process:
+ \n1. Verify that the DUT supports USB or Analog audio peripherals.
+ \n2. Press the \"Record\" button.
+ \n3. Connect a wired input peripheral. A connect routing message should appear.
+ \n4. Press the \"Stop\" button.
+ \n\nTest Criteria:
+ \nThe test passes if either the device DOES NOT support wired input peripherals, or
+ the routing notifications are received.
</string>
<!--- AudioOutputRoutingNotificationsActivity -->
<string name="audio_output_routingnotifications_test">Audio Output Routing Notifications Test</string>
<string name="audio_output_routingnotification_instructions">
- Click on the "Play" button in the AudioTrack Routing Notifications section below to
- start (silent) playback. Insert a wired headset. Observe a message acknowledging the
- rerouting event below. Remove the wired headset and observe the new routing message.
- Click on the "Stop" button to stop playback.\n
+ Test whether appropriate output routing notifications are sent when audio output peripherals are
+ connected to the device.
+ \n\nTest Setup:
+ \nDisconnect any wired audio peripherals.
+ \n\nTest Process:
+ \n1. Verify that the DUT supports USB or Analog audio peripherals.
+ \n2. Press the \"Play\" button.
+ \n3. Connect a wired output peripheral. A connect routing message should appear.
+ \n4. Press the \"Stop\" button.
+ \n\nTest Criteria:
+ \nThe test passes if either the device DOES NOT support wired output peripherals, or
+ the routing notifications are received.
</string>
- <string name="audio_routingnotification_playBtn">Play</string>
- <string name="audio_routingnotification_playStopBtn">Stop</string>
- <string name="audio_routingnotification_recBtn">Record</string>
- <string name="audio_routingnotification_recStopBtn">Stop</string>
<string name="audio_routingnotification_playHeader">AudioTrack Routing Notifications</string>
<string name="audio_routingnotification_recHeader">AudioRecord Routing Notifications</string>
<string name="audio_routingnotification_trackRoutingMsg">AudioTrack rerouting</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java
index eb28c49..7ceb195 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java
@@ -16,8 +16,6 @@
package com.android.cts.verifier.audio;
-import com.android.cts.verifier.R;
-
import android.content.Context;
import android.media.AudioDeviceCallback;
@@ -37,11 +35,20 @@
import android.widget.Button;
import android.widget.TextView;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.cts.verifier.CtsVerifierReportLog;
+import com.android.cts.verifier.R;
+
import org.hyphonate.megaaudio.recorder.RecorderBuilder;
import org.hyphonate.megaaudio.recorder.Recorder;
import org.hyphonate.megaaudio.recorder.JavaRecorder;
import org.hyphonate.megaaudio.recorder.sinks.NopAudioSinkProvider;
+import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
+import static com.android.cts.verifier.TestListAdapter.setTestNameSuffix;
+
/*
* Tests AudioRecord (re)Routing messages.
*/
@@ -63,6 +70,11 @@
JavaRecorder mAudioRecorder;
+ boolean mRoutingNotificationReceived;
+
+ // ReportLog schema
+ protected static final String SECTION_INPUT_ROUTING = "audio_in_routing_notifications";
+
private class OnBtnClickListener implements OnClickListener {
@Override
public void onClick(View v) {
@@ -78,12 +90,13 @@
AudioRecord audioRecord = mAudioRecorder.getAudioRecord();
audioRecord.addOnRoutingChangedListener(
new AudioRecordRoutingChangeListener(), new Handler());
-
+ enableTestButtons(false);
}
break;
case R.id.audio_routingnotification_recordStopBtn:
mAudioRecorder.stopStream();
+ enableTestButtons(true);
break;
}
}
@@ -98,21 +111,45 @@
R.string.audio_routingnotification_recordRoutingMsg);
AudioDeviceInfo routedDevice = audioRecord.getRoutedDevice();
CharSequence deviceName = routedDevice != null ? routedDevice.getProductName() : "none";
+ mConnectedPeripheralName = deviceName.toString();
int deviceType = routedDevice != null ? routedDevice.getType() : -1;
textView.setText(msg + " - " +
deviceName + " [0x" + Integer.toHexString(deviceType) + "]" +
" - " + mNumRecordNotifications);
+
+ mRoutingNotificationReceived = true;
+ calculatePass();
}
}
@Override
protected void enableTestButtons(boolean enabled) {
recordBtn.setEnabled(enabled);
- stopBtn.setEnabled(enabled);
+ stopBtn.setEnabled(!enabled);
}
@Override
protected void calculatePass() {
+ getPassButton().setEnabled(mRoutingNotificationReceived || !mSupportsWiredPeripheral);
+ if (mRoutingNotificationReceived) {
+ ((TextView) findViewById(R.id.audio_routingnotification_testresult)).setText(
+ "Test PASSES - Routing notification received");
+ } else if (!mSupportsWiredPeripheral) {
+ ((TextView) findViewById(
+ R.id.audio_routingnotification_testresult)).setText(
+ "Test PASSES - No peripheral support");
+ }
+ }
+
+ protected void storeTestResults() {
+ super.storeTestResults();
+
+ CtsVerifierReportLog reportLog = getReportLog();
+ reportLog.addValue(
+ KEY_ROUTING_RECEIVED,
+ mRoutingNotificationReceived ? 1 : 0,
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
}
@Override
@@ -123,8 +160,10 @@
Button btn;
recordBtn = (Button)findViewById(R.id.audio_routingnotification_recordBtn);
recordBtn.setOnClickListener(mBtnClickListener);
+ recordBtn.setEnabled(false);
stopBtn = (Button)findViewById(R.id.audio_routingnotification_recordStopBtn);
stopBtn.setOnClickListener(mBtnClickListener);
+ stopBtn.setEnabled(false);
mContext = this;
@@ -146,6 +185,14 @@
super.setup();
setPassFailButtonClickListeners();
+ getPassButton().setEnabled(false);
+ setInfoResources(R.string.audio_input_routingnotifications_test,
+ R.string.audio_input_routingnotification_instructions, -1);
+ }
+
+ @Override
+ public final String getReportSectionName() {
+ return setTestNameSuffix(sCurrentDisplayMode, SECTION_INPUT_ROUTING);
}
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java
index ba2fdcf..0231e51 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java
@@ -16,8 +16,6 @@
package com.android.cts.verifier.audio;
-import com.android.cts.verifier.R;
-
import android.content.Context;
import android.media.AudioDeviceCallback;
@@ -36,12 +34,21 @@
import android.widget.Button;
import android.widget.TextView;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import com.android.cts.verifier.CtsVerifierReportLog;
+import com.android.cts.verifier.R;
+
import org.hyphonate.megaaudio.player.AudioSource;
import org.hyphonate.megaaudio.player.AudioSourceProvider;
import org.hyphonate.megaaudio.player.JavaPlayer;
import org.hyphonate.megaaudio.player.PlayerBuilder;
import org.hyphonate.megaaudio.player.sources.SinAudioSourceProvider;
+import static com.android.cts.verifier.TestListActivity.sCurrentDisplayMode;
+import static com.android.cts.verifier.TestListAdapter.setTestNameSuffix;
+
/**
* Tests AudioTrack and AudioRecord (re)Routing messages.
*/
@@ -63,6 +70,11 @@
// Mega Player
JavaPlayer mAudioPlayer;
+ boolean mRoutingNotificationReceived;
+
+ // ReportLog schema
+ private static final String SECTION_OUTPUT_ROUTING = "audio_out_routing_notifications";
+
private class OnBtnClickListener implements OnClickListener {
@Override
public void onClick(View v) {
@@ -76,11 +88,13 @@
AudioTrack audioTrack = mAudioPlayer.getAudioTrack();
audioTrack.addOnRoutingChangedListener(
new AudioTrackRoutingChangeListener(), new Handler());
+ enableTestButtons(false);
}
break;
case R.id.audio_routingnotification_playStopBtn:
mAudioPlayer.stopStream();
+ enableTestButtons(true);
break;
}
}
@@ -95,21 +109,45 @@
R.string.audio_routingnotification_trackRoutingMsg);
AudioDeviceInfo routedDevice = audioTrack.getRoutedDevice();
CharSequence deviceName = routedDevice != null ? routedDevice.getProductName() : "none";
+ mConnectedPeripheralName = deviceName.toString();
int deviceType = routedDevice != null ? routedDevice.getType() : -1;
textView.setText(msg + " - " +
deviceName + " [0x" + Integer.toHexString(deviceType) + "]" +
" - " + mNumTrackNotifications);
+ mRoutingNotificationReceived = true;
+ calculatePass();
}
}
@Override
protected void enableTestButtons(boolean enabled) {
playBtn.setEnabled(enabled);
- stopBtn.setEnabled(enabled);
+ stopBtn.setEnabled(!enabled);
}
@Override
protected void calculatePass() {
+ getPassButton().setEnabled(mRoutingNotificationReceived || !mSupportsWiredPeripheral);
+ if (mRoutingNotificationReceived) {
+ ((TextView) findViewById(R.id.audio_routingnotification_testresult)).setText(
+ "Test PASSES - Routing notification received");
+ } else if (!mSupportsWiredPeripheral) {
+ ((TextView) findViewById(
+ R.id.audio_routingnotification_testresult)).setText(
+ "Test PASSES - No peripheral support");
+ }
+
+ }
+
+ protected void storeTestResults() {
+ super.storeTestResults();
+
+ CtsVerifierReportLog reportLog = getReportLog();
+ reportLog.addValue(
+ KEY_ROUTING_RECEIVED,
+ mRoutingNotificationReceived ? 1 : 0,
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
}
@Override
@@ -121,8 +159,10 @@
playBtn = (Button)findViewById(R.id.audio_routingnotification_playBtn);
playBtn.setOnClickListener(mBtnClickListener);
+ playBtn.setEnabled(false);
stopBtn = (Button)findViewById(R.id.audio_routingnotification_playStopBtn);
stopBtn.setOnClickListener(mBtnClickListener);
+ stopBtn.setEnabled(false);
// Setup Player
//
@@ -147,6 +187,14 @@
super.setup();
setPassFailButtonClickListeners();
+ getPassButton().setEnabled(false);
+ setInfoResources(R.string.audio_output_routingnotifications_test,
+ R.string.audio_output_routingnotification_instructions, -1);
+ }
+
+ @Override
+ public final String getReportSectionName() {
+ return setTestNameSuffix(sCurrentDisplayMode, SECTION_OUTPUT_ROUTING);
}
@Override
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java
index 687e877..b6d15b3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioWiredDeviceBaseActivity.java
@@ -16,9 +16,6 @@
package com.android.cts.verifier.audio;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
import com.android.compatibility.common.util.ReportLog;
import com.android.compatibility.common.util.ResultType;
import com.android.compatibility.common.util.ResultUnit;
@@ -35,6 +32,10 @@
import android.widget.Button;
+import com.android.cts.verifier.CtsVerifierReportLog;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
abstract class AudioWiredDeviceBaseActivity extends PassFailButtons.Activity {
private static final String TAG = AudioWiredDeviceBaseActivity.class.getSimpleName();
@@ -44,27 +45,21 @@
private Button mDoesntSupportBtn;
protected boolean mSupportsWiredPeripheral;
+ protected String mConnectedPeripheralName;
abstract protected void enableTestButtons(boolean enabled);
abstract protected void calculatePass();
// ReportLog schema
private static final String KEY_WIRED_PORT_SUPPORTED = "wired_port_supported";
-
- private void recordWiredPortFound() {
- getReportLog().addValue(
- KEY_WIRED_PORT_SUPPORTED,
- mSupportsWiredPeripheral ? 1 : 0,
- ResultType.NEUTRAL,
- ResultUnit.NONE);
- }
+ protected static final String KEY_SUPPORTS_PERIPHERALS = "supports_wired_peripherals";
+ protected static final String KEY_ROUTING_RECEIVED = "routing_received";
+ protected static final String KEY_CONNECTED_PERIPHERAL = "routing_connected_peripheral";
protected void setup() {
// The "Honor" system buttons
(mSupportsBtn = (Button)findViewById(R.id.audio_wired_no)).setOnClickListener(mBtnClickListener);
(mDoesntSupportBtn = (Button)findViewById(R.id.audio_wired_yes)).setOnClickListener(mBtnClickListener);
-
- enableTestButtons(false);
}
private class OnBtnClickListener implements OnClickListener {
@@ -84,11 +79,25 @@
}
Log.i(TAG, "Wired Device Support:" + mSupportsWiredPeripheral);
enableTestButtons(mSupportsWiredPeripheral);
- recordWiredPortFound();
calculatePass();
}
}
+ protected void storeTestResults() {
+ CtsVerifierReportLog reportLog = getReportLog();
+ reportLog.addValue(
+ KEY_WIRED_PORT_SUPPORTED,
+ mSupportsWiredPeripheral ? 1 : 0,
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+
+ reportLog.addValue(
+ KEY_CONNECTED_PERIPHERAL,
+ mConnectedPeripheralName,
+ ResultType.NEUTRAL,
+ ResultUnit.NONE);
+ }
+
//
// PassFailButtons Overrides
//
@@ -97,6 +106,8 @@
@Override
public void recordTestResults() {
+ storeTestResults();
+
getReportLog().submit();
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
index dbe2c14..83d00a9 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
@@ -290,6 +290,10 @@
return (hasSettingsActivity(context, Settings.ACTION_DISPLAY_SETTINGS)
&& !pm.hasSystemFeature(PackageManager.FEATURE_WATCH));
case UserManager.DISALLOW_CONFIG_CELL_BROADCASTS:
+ if (context.getResources().getBoolean(context.getResources()
+ .getIdentifier("config_disable_all_cb_messages", "bool", "android"))) {
+ return false;
+ }
final TelephonyManager tm =
context.getSystemService(TelephonyManager.class);
if (!tm.isSmsCapable()) {
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 5b19e7b..9451c60 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
@@ -68,7 +68,7 @@
private static final int CAPABILITIES_CHANGED_FOR_METERED_TIMEOUT_MS = 80_000;
private final Object mLock = new Object();
- private final ScheduledExecutorService mExecutorService;
+ private static ScheduledExecutorService sExecutorService;
private final WifiNetworkSuggestion.Builder mNetworkSuggestionBuilder =
new WifiNetworkSuggestion.Builder();
@@ -101,7 +101,6 @@
boolean setRequiresAppInteraction, boolean simulateConnectionFailure,
boolean setMeteredPostConnection) {
super(context);
- mExecutorService = Executors.newSingleThreadScheduledExecutor();
mSetBssid = setBssid;
mSetRequiresAppInteraction = setRequiresAppInteraction;
mSimulateConnectionFailure = simulateConnectionFailure;
@@ -299,7 +298,7 @@
// Step: Trigger scans periodically to trigger network selection quicker.
if (DBG) Log.v(TAG, "Triggering scan periodically");
- mExecutorService.scheduleAtFixedRate(() -> {
+ sExecutorService.scheduleAtFixedRate(() -> {
if (!mWifiManager.startScan()) {
Log.w(TAG, "Failed to trigger scan");
}
@@ -459,12 +458,13 @@
@Override
protected void setUp() {
super.setUp();
+ sExecutorService = Executors.newSingleThreadScheduledExecutor();
mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
}
@Override
protected void tearDown() {
- mExecutorService.shutdownNow();
+ sExecutorService.shutdownNow();
if (mBroadcastReceiver != null) {
mContext.unregisterReceiver(mBroadcastReceiver);
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
index 70c9362..b8562ab 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/PropertyUtil.java
@@ -38,13 +38,14 @@
* shipped. Property should be undefined for factory ROM products.
*/
public static final String FIRST_API_LEVEL = "ro.product.first_api_level";
+ private static final String BOARD_API_LEVEL = "ro.board.api_level";
+ private static final String BOARD_FIRST_API_LEVEL = "ro.board.first_api_level";
private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
+ private static final String CAMERAX_EXTENSIONS_ENABLED = "ro.camerax.extensions.enabled";
private static final String MANUFACTURER_PROPERTY = "ro.product.manufacturer";
private static final String TAG_DEV_KEYS = "dev-keys";
- private static final String VENDOR_API_LEVEL = "ro.board.api_level";
- private static final String VENDOR_FIRST_API_LEVEL = "ro.board.first_api_level";
+ private static final String VENDOR_BUILD_VERSION_SDK = "ro.vendor.build.version.sdk";
private static final String VNDK_VERSION = "ro.vndk.version";
- private static final String CAMERAX_EXTENSIONS_ENABLED = "ro.camerax.extensions.enabled";
public static final String GOOGLE_SETTINGS_QUERY =
"content query --uri content://com.google.settings/partner";
@@ -89,6 +90,23 @@
}
/**
+ * Return the API level that the VSR requirement must be fulfilled. It reads
+ * ro.product.first_api_level, ro.board.first_api_level, and ro.board.api_level
+ * to find the minimum required VSR api_level for the DUT.
+ */
+ public static int getVsrApiLevel() {
+ // Api level properties of the board. The order of the properties must be kept.
+ String[] boardApiLevelProps = { BOARD_API_LEVEL, BOARD_FIRST_API_LEVEL, VENDOR_BUILD_VERSION_SDK };
+ for (String apiLevelProp : boardApiLevelProps) {
+ int apiLevel = getPropertyInt(apiLevelProp);
+ if (apiLevel != INT_VALUE_IF_UNSET) {
+ return Math.min(apiLevel, getFirstApiLevel());
+ }
+ }
+ return getFirstApiLevel();
+ }
+
+ /**
* Return the API level of the vendor partition. It will read the following properties in order
* and returns the value of the first defined property. If none of them are defined, or the
* value is a VERSION CODENAME, returns the current API level which is defined in
@@ -103,7 +121,7 @@
public static int getVendorApiLevel() {
String[] vendorApiLevelProps = {
// Use the properties in order.
- VENDOR_API_LEVEL, VENDOR_FIRST_API_LEVEL, VNDK_VERSION,
+ BOARD_API_LEVEL, BOARD_FIRST_API_LEVEL, VNDK_VERSION,
};
for (String prop : vendorApiLevelProps) {
int apiLevel = getPropertyInt(prop);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
index 75bcdf1..974ab7b 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionsParentTest.java
@@ -115,7 +115,7 @@
}
public void testUserRestrictionDisallowConfigDateTimeIsNotPersisted() throws Exception {
- final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(30);
+ final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(60);
while (System.nanoTime() <= deadline) {
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)) {
return;
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfilePasswordTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfilePasswordTest.java
index 77e1838..0d11e0a 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfilePasswordTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfilePasswordTest.java
@@ -127,7 +127,7 @@
@LockSettingsTest
@Test
public void testUnlockWorkProfile_deviceWidePassword() throws Exception {
- assumeHasSecureLockScreenFeature();
+ assumeHasFileBasedEncryptionAndSecureLockScreenFeatures();
try {
// Add a device password after the work profile has been created.
diff --git a/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_long.mp4 b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_long.mp4
index 6b37153..c8d4b8f 100755
--- a/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_long.mp4
+++ b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_long.mp4
Binary files differ
diff --git a/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_medium.mp4 b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_medium.mp4
index 207530c..96cf7b1 100755
--- a/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_medium.mp4
+++ b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_medium.mp4
Binary files differ
diff --git a/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_small.mp4 b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_small.mp4
index f2aa045..b2b0f5d 100755
--- a/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_small.mp4
+++ b/tests/MediaProviderTranscode/res/raw/testVideo_HEVC_small.mp4
Binary files differ
diff --git a/tests/MediaProviderTranscode/res/raw/testVideo_Legacy.mp4 b/tests/MediaProviderTranscode/res/raw/testVideo_Legacy.mp4
index 1c74ffa..001667d 100755
--- a/tests/MediaProviderTranscode/res/raw/testVideo_Legacy.mp4
+++ b/tests/MediaProviderTranscode/res/raw/testVideo_Legacy.mp4
Binary files differ
diff --git a/tests/MediaProviderTranscode/res/raw/testvideo_HEVC.mp4 b/tests/MediaProviderTranscode/res/raw/testvideo_HEVC.mp4
index 8a3dba2..fcc1bb4 100644
--- a/tests/MediaProviderTranscode/res/raw/testvideo_HEVC.mp4
+++ b/tests/MediaProviderTranscode/res/raw/testvideo_HEVC.mp4
Binary files differ
diff --git a/tests/accessibilityservice/res/values/strings.xml b/tests/accessibilityservice/res/values/strings.xml
index dd59c0b..7cba07a 100644
--- a/tests/accessibilityservice/res/values/strings.xml
+++ b/tests/accessibilityservice/res/values/strings.xml
@@ -57,34 +57,34 @@
<string name="accessibility_query_window_test_activity">Query window test</string>
<!-- String Button1 text -->
- <string name="button1">B1</string>
+ <string name="button1">Btn1</string>
<!-- String Button2 text -->
- <string name="button2">B2</string>
+ <string name="button2">Btn2</string>
<!-- String Button3 text -->
- <string name="button3">B3</string>
+ <string name="button3">Btn3</string>
<!-- String Button4 text -->
- <string name="button4">B4</string>
+ <string name="button4">Btn4</string>
<!-- String Button5 text -->
- <string name="button5">B5</string>
+ <string name="button5">Btn5</string>
<!-- String Button6 text -->
- <string name="button6">B6</string>
+ <string name="button6">Btn6</string>
<!-- String with content description for Button6 -->
<string name="contentDescription">contentDescription</string>
<!-- String Button7 text -->
- <string name="button7">B7</string>
+ <string name="button7">Btn7</string>
<!-- String Button8 text -->
- <string name="button8">B8</string>
+ <string name="button8">Btn8</string>
<!-- String Button9 text -->
- <string name="button9">B9</string>
+ <string name="button9">Btn9</string>
<!-- AccessibilityFocusTest -->
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
index ecdab0f..eb9f037 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityWindowQueryTest.java
@@ -912,15 +912,16 @@
classNameAndTextList.add("android.widget.LinearLayout");
classNameAndTextList.add("android.widget.LinearLayout");
classNameAndTextList.add("android.widget.LinearLayout");
- classNameAndTextList.add("android.widget.ButtonB1");
- classNameAndTextList.add("android.widget.ButtonB2");
- classNameAndTextList.add("android.widget.ButtonB3");
- classNameAndTextList.add("android.widget.ButtonB4");
- classNameAndTextList.add("android.widget.ButtonB5");
- classNameAndTextList.add("android.widget.ButtonB6");
- classNameAndTextList.add("android.widget.ButtonB7");
- classNameAndTextList.add("android.widget.ButtonB8");
- classNameAndTextList.add("android.widget.ButtonB9");
+ final String btnClass = "android.widget.Button";
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button1)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button2)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button3)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button4)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button5)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button6)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button7)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button8)));
+ classNameAndTextList.add(btnClass.concat(mActivity.getString(R.string.button9)));
boolean verifyContent = false;
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
old mode 100644
new mode 100755
index 67ac550..f91cdf6
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -4467,7 +4467,7 @@
@Override
public void handleMessage(Message message) {
- mEvents.computeIfAbsent(message.what, e -> new CompletableFuture<>()).complete(
+ mEvents.computeIfAbsent(message.what, e -> new CompletableFuture<>()).obtrudeValue(
message.arg1);
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
index 074b422..f821d68 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/DuplicateIdActivityTest.java
@@ -19,6 +19,7 @@
import static android.autofillservice.cts.activities.DuplicateIdActivity.DUPLICATE_ID;
import static android.autofillservice.cts.testcore.CannedFillResponse.NO_RESPONSE;
import static android.autofillservice.cts.testcore.Helper.assertEqualsIgnoreSession;
+import static android.autofillservice.cts.testcore.Helper.getActivityTitle;
import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
@@ -34,12 +35,15 @@
import android.autofillservice.cts.testcore.CannedFillResponse;
import android.autofillservice.cts.testcore.Helper;
import android.autofillservice.cts.testcore.InstrumentedAutoFillService;
+import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.autofill.AutofillId;
import android.widget.EditText;
+import androidx.test.InstrumentationRegistry;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -77,9 +81,17 @@
* @return An array containing the two tested views
*/
private AssistStructure.ViewNode[] findViews(InstrumentedAutoFillService.FillRequest request,
- int expectedCount) {
- assertThat(request.structure.getWindowNodeCount()).isEqualTo(1);
- AssistStructure.WindowNode windowNode = request.structure.getWindowNodeAt(0);
+ int expectedCount, String activityTitle) {
+ AssistStructure.WindowNode windowNode = null;
+ int count = 0;
+ final int nodes = request.structure.getWindowNodeCount();
+ for (int i = 0; i < nodes; ++i) {
+ if (TextUtils.equals(request.structure.getWindowNodeAt(i).getTitle(), activityTitle)) {
+ windowNode = request.structure.getWindowNodeAt(i);
+ count++;
+ }
+ }
+ assertThat(count).isEqualTo(1);
AssistStructure.ViewNode rootNode = windowNode.getRootViewNode();
@@ -110,7 +122,9 @@
final InstrumentedAutoFillService.FillRequest request1 = sReplier.getNextFillRequest();
Log.v(TAG, "request1: " + request1);
- final AssistStructure.ViewNode[] views1 = findViews(request1, 2);
+ final String activityTitle = getActivity().getPackageName() + "/"
+ + getActivityTitle(InstrumentationRegistry.getInstrumentation(), getActivity());
+ final AssistStructure.ViewNode[] views1 = findViews(request1, 2, activityTitle);
final AssistStructure.ViewNode view1 = views1[0];
final AssistStructure.ViewNode view2 = views1[1];
final AutofillId id1 = view1.getAutofillId();
@@ -148,7 +162,7 @@
final InstrumentedAutoFillService.FillRequest request3 = sReplier.getNextFillRequest();
Log.v(TAG, "request3: " + request3);
- final AssistStructure.ViewNode[] views2 = findViews(request3, 3);
+ final AssistStructure.ViewNode[] views2 = findViews(request3, 3, activityTitle);
final AssistStructure.ViewNode recreatedView1 = views2[0];
final AssistStructure.ViewNode recreatedView2 = views2[1];
final AssistStructure.ViewNode newView1 = views2[2];
diff --git a/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java
index d4c9863..1880ed3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/dropdown/LoginActivityTest.java
@@ -31,7 +31,7 @@
import static android.autofillservice.cts.testcore.Helper.ID_USERNAME_LABEL;
import static android.autofillservice.cts.testcore.Helper.allowOverlays;
import static android.autofillservice.cts.testcore.Helper.assertHasFlags;
-import static android.autofillservice.cts.testcore.Helper.assertNumberOfChildren;
+import static android.autofillservice.cts.testcore.Helper.assertNumberOfChildrenWithWindowTitle;
import static android.autofillservice.cts.testcore.Helper.assertTextAndValue;
import static android.autofillservice.cts.testcore.Helper.assertTextIsSanitized;
import static android.autofillservice.cts.testcore.Helper.assertTextOnly;
@@ -41,6 +41,7 @@
import static android.autofillservice.cts.testcore.Helper.dumpStructure;
import static android.autofillservice.cts.testcore.Helper.findAutofillIdByResourceId;
import static android.autofillservice.cts.testcore.Helper.findNodeByResourceId;
+import static android.autofillservice.cts.testcore.Helper.getActivityTitle;
import static android.autofillservice.cts.testcore.Helper.isAutofillWindowFullScreen;
import static android.autofillservice.cts.testcore.Helper.setUserComplete;
import static android.autofillservice.cts.testcore.InstrumentedAutoFillService.SERVICE_CLASS;
@@ -116,6 +117,7 @@
import android.widget.EditText;
import android.widget.RemoteViews;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
import com.android.compatibility.common.util.RetryableException;
@@ -2095,7 +2097,10 @@
// But it also has an intermediate container (for username) that should be included because
// it has a resource id.
- assertNumberOfChildren(fillRequest.structure, 12);
+ // get activity title
+ final CharSequence activityTitle = mActivity.getPackageName() + "/"
+ + getActivityTitle(InstrumentationRegistry.getInstrumentation(), mActivity);
+ assertNumberOfChildrenWithWindowTitle(fillRequest.structure, 12, activityTitle);
// Make sure container with a resource id was included:
final ViewNode usernameContainer = findNodeByResourceId(fillRequest.structure,
diff --git a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
index c2dfb13..21befa5 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/testcore/Helper.java
@@ -33,6 +33,7 @@
import static com.google.common.truth.Truth.assertWithMessage;
import android.app.Activity;
+import android.app.Instrumentation;
import android.app.PendingIntent;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
@@ -758,10 +759,9 @@
/**
* Asserts the number of children in the Assist structure.
*/
- public static void assertNumberOfChildren(AssistStructure structure, int expected) {
- assertWithMessage("wrong number of nodes").that(structure.getWindowNodeCount())
- .isEqualTo(1);
- final int actual = getNumberNodes(structure);
+ public static void assertNumberOfChildrenWithWindowTitle(AssistStructure structure,
+ int expected, CharSequence windowTitle) {
+ final int actual = getNumberNodes(structure, windowTitle);
if (actual != expected) {
dumpStructure("assertNumberOfChildren()", structure);
throw new AssertionError("assertNumberOfChildren() for structure failed: expected "
@@ -772,18 +772,31 @@
/**
* Gets the total number of nodes in an structure.
*/
- public static int getNumberNodes(AssistStructure structure) {
+ public static int getNumberNodes(AssistStructure structure,
+ CharSequence windowTitle) {
int count = 0;
final int nodes = structure.getWindowNodeCount();
for (int i = 0; i < nodes; i++) {
final WindowNode windowNode = structure.getWindowNodeAt(i);
- final ViewNode rootNode = windowNode.getRootViewNode();
- count += getNumberNodes(rootNode);
+ if (windowNode.getTitle().equals(windowTitle)) {
+ final ViewNode rootNode = windowNode.getRootViewNode();
+ count += getNumberNodes(rootNode);
+ }
}
return count;
}
/**
+ * Gets the activity title.
+ */
+ public static CharSequence getActivityTitle(Instrumentation instrumentation,
+ Activity activity) {
+ final StringBuilder titleBuilder = new StringBuilder();
+ instrumentation.runOnMainSync(() -> titleBuilder.append(activity.getTitle()));
+ return titleBuilder;
+ }
+
+ /**
* Gets the total number of nodes in an node, including all descendants and the node itself.
*/
public static int getNumberNodes(ViewNode node) {
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
index 81198f7..891aefa 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
@@ -15,23 +15,13 @@
*/
package android.contentcaptureservice.cts;
-import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
-import static android.contentcaptureservice.cts.Assertions.assertSessionPaused;
-import static android.contentcaptureservice.cts.Assertions.assertSessionResumed;
-import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
-import static android.contentcaptureservice.cts.Assertions.assertViewTreeFinished;
-import static android.contentcaptureservice.cts.Assertions.assertViewTreeStarted;
-import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
-
-import static com.google.common.truth.Truth.assertThat;
import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.util.Log;
import android.view.View;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureSessionId;
-import android.view.contentcapture.ViewNode;
import androidx.annotation.NonNull;
@@ -51,20 +41,13 @@
final List<ContentCaptureEvent> events = session.getEvents();
Log.v(TAG, "events(" + events.size() + "): " + events);
- final int minEvents = 9; // TODO(b/122315042): disappeared not always sent
- assertThat(events.size()).isAtLeast(minEvents);
-
- assertSessionResumed(events, 0);
- assertViewTreeStarted(events, 1);
- assertDecorViewAppeared(events, 2, decorView);
- // TODO(b/123540067): ignoring 3 intermediate parents
- final ViewNode title = assertViewAppeared(events, 6).getViewNode();
- assertThat(title.getText()).isEqualTo("Blanka");
- assertViewTreeFinished(events, 7);
- assertSessionPaused(events, 8);
- if (false) { // TODO(b/123540067): disabled because it includes the parent
- assertViewsOptionallyDisappeared(events, minEvents, decorView.getAutofillId(),
- title.getAutofillId());
- }
+ new EventsAssertor(events)
+ .isAtLeast(9)
+ .assertSessionResumed()
+ .assertViewTreeStarted()
+ .assertDecorViewAppeared(decorView)
+ .assertViewAppeared("Blanka")
+ .assertViewTreeFinished()
+ .assertSessionPaused();
}
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
index c603f77..aa83153 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
@@ -18,7 +18,6 @@
import static android.contentcaptureservice.cts.Assertions.LifecycleOrder.CREATION;
import static android.contentcaptureservice.cts.Assertions.LifecycleOrder.DESTRUCTION;
import static android.contentcaptureservice.cts.Assertions.assertChildSessionContext;
-import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
import static android.contentcaptureservice.cts.Assertions.assertLifecycleOrder;
import static android.contentcaptureservice.cts.Assertions.assertMainSessionContext;
import static android.contentcaptureservice.cts.Assertions.assertNoViewLevelEvents;
@@ -312,20 +311,20 @@
final View grandpa2 = activity.getGrandGrandParent();
final View decorView = activity.getDecorView();
- // Assert just the relevant events
- assertThat(events.size()).isAtLeast(12);
- assertSessionResumed(events, 0);
- assertViewTreeStarted(events, 1);
- assertDecorViewAppeared(events, 2, decorView);
- assertViewAppeared(events, 3, grandpa2, decorView.getAutofillId());
- assertViewAppeared(events, 4, grandpa1, grandpa2.getAutofillId());
- assertViewAppeared(events, 5, sessionId, rootView, grandpa1.getAutofillId());
- assertViewAppeared(events, 6, sessionId, child, rootId);
- assertViewTreeFinished(events, 7);
- assertViewTreeStarted(events, 8);
- assertViewDisappeared(events, 9, child.getAutofillId());
- assertViewTreeFinished(events, 10);
- assertSessionPaused(events, 11);
+ new EventsAssertor(events)
+ .isAtLeast(12)
+ .assertSessionResumed()
+ .assertViewTreeStarted()
+ .assertDecorViewAppeared(decorView)
+ .assertViewAppeared(grandpa2, decorView.getAutofillId())
+ .assertViewAppeared(grandpa1, grandpa2.getAutofillId())
+ .assertViewAppeared(sessionId, rootView, grandpa1.getAutofillId())
+ .assertViewAppeared(sessionId, child, rootId)
+ .assertViewTreeFinished()
+ .assertViewTreeStarted()
+ .assertViewDisappeared(child.getAutofillId())
+ .assertViewTreeFinished()
+ .assertSessionPaused();
// TODO(b/122315042): assert parents disappeared
}
@@ -358,15 +357,14 @@
final View grandpa = activity.getGrandParent();
// Assert just the relevant events
-
- assertThat(events.size()).isAtLeast(6);
- // TODO(b/122959591): figure out the child is coming first
- assertSessionResumed(events, 0);
- assertViewTreeStarted(events, 1);
- assertViewAppeared(events, 2, sessionId, child, rootView.getAutofillId());
- assertViewAppeared(events, 3, sessionId, rootView, grandpa.getAutofillId());
- assertViewTreeFinished(events, 4);
- assertSessionPaused(events, 5);
+ new EventsAssertor(events)
+ .isAtLeast(6)
+ .assertSessionResumed()
+ .assertViewTreeStarted()
+ .assertViewAppeared(sessionId, child, rootView.getAutofillId())
+ .assertViewAppeared(sessionId, rootView, grandpa.getAutofillId())
+ .assertViewTreeFinished()
+ .assertSessionPaused();
}
@Test
@@ -408,22 +406,25 @@
final List<ContentCaptureEvent> mainEvents = mainTestSession.getEvents();
Log.v(TAG, "mainEvents(" + mainEvents.size() + "): " + mainEvents);
- assertThat(mainEvents.size()).isAtLeast(5);
- assertSessionResumed(mainEvents, 0);
- assertViewTreeStarted(mainEvents, 1);
- assertViewAppeared(mainEvents, 2, mainSessionId, rootView, grandpa.getAutofillId());
- assertViewTreeFinished(mainEvents, 3);
- assertSessionPaused(mainEvents, 4);
+ new EventsAssertor(mainEvents)
+ .isAtLeast(5)
+ .assertSessionResumed()
+ .assertViewTreeStarted()
+ .assertViewAppeared(mainSessionId, rootView, grandpa.getAutofillId())
+ .assertViewTreeFinished()
+ .assertSessionPaused();
final Session childTestSession = service.getFinishedSession(childSessionId);
assertChildSessionContext(childTestSession, "child");
final List<ContentCaptureEvent> childEvents = childTestSession.getEvents();
Log.v(TAG, "childEvents(" + childEvents.size() + "): " + childEvents);
final int minEvents = 3;
- assertThat(childEvents.size()).isAtLeast(minEvents);
- assertViewTreeStarted(childEvents, 0);
- assertViewAppeared(childEvents, 1, childSessionId, child, rootView.getAutofillId());
- assertViewTreeFinished(childEvents, 2);
+ new EventsAssertor(childEvents)
+ .isAtLeast(3)
+ .assertViewTreeStarted()
+ .assertViewAppeared(childSessionId, child, rootView.getAutofillId())
+ .assertViewTreeFinished();
+
// TODO(b/122315042): assert parents disappeared
}
@@ -726,37 +727,40 @@
final AutofillId rootId = rootView.getAutofillId();
final View grandpa = activity.getGrandParent();
- assertThat(mainEvents).hasSize(8);
- assertSessionResumed(mainEvents, 0);
- assertViewTreeStarted(mainEvents, 1);
- assertViewAppeared(mainEvents, 2, rootView, grandpa.getAutofillId());
- assertViewTreeFinished(mainEvents, 3);
- assertSessionPaused(mainEvents, 4); // TODO(b/122959591): investigate why
- assertViewTreeStarted(mainEvents, 5);
- assertViewDisappeared(mainEvents, 6, rootId);
- assertViewTreeFinished(mainEvents, 7);
+ new EventsAssertor(mainEvents)
+ .isAtLeast(8)
+ .assertSessionResumed()
+ .assertViewTreeStarted()
+ .assertViewAppeared(rootView, grandpa.getAutofillId())
+ .assertViewTreeFinished()
+ .assertSessionPaused()
+ .assertViewTreeStarted()
+ .assertViewDisappeared(rootId)
+ .assertViewTreeFinished();
- assertThat(events1).hasSize(3);
- assertViewTreeStarted(events1, 0);
- assertViewAppeared(events1, 1, s1c1, rootId);
- assertViewTreeFinished(events1, 2);
+ new EventsAssertor(events1)
+ .isAtLeast(3)
+ .assertViewTreeStarted()
+ .assertViewAppeared(s1c1, rootId)
+ .assertViewTreeFinished();
- assertThat(events2.size()).isAtLeast(4);
- assertViewTreeStarted(events2, 0);
- assertViewAppeared(events2, 1, s2c1, rootId);
- assertViewAppeared(events2, 2, s2c2, rootId);
- assertViewTreeFinished(events2, 3);
- // TODO(b/122315042): assert parents disappeared
+ new EventsAssertor(events2)
+ .isAtLeast(4)
+ .assertViewTreeStarted()
+ .assertViewAppeared(s2c1, rootId)
+ .assertViewAppeared(s2c2, rootId)
+ .assertViewTreeFinished();
- assertThat(events3).hasSize(8);
- assertViewTreeStarted(events3, 0);
- assertViewAppeared(events3, 1, s3c1, rootId);
- assertViewAppeared(events3, 2, s3c2, rootId);
- assertViewTreeFinished(events3, 3);
- assertViewTreeStarted(events3, 4);
- assertViewDisappeared(events3, 5, s3c1.getAutofillId());
- assertViewAppeared(events3, 6, s3c3, rootId);
- assertViewTreeFinished(events3, 7);
+ new EventsAssertor(events3)
+ .isAtLeast(8)
+ .assertViewTreeStarted()
+ .assertViewAppeared(s3c1, rootId)
+ .assertViewAppeared(s3c2, rootId)
+ .assertViewTreeFinished()
+ .assertViewTreeStarted()
+ .assertViewDisappeared(s3c1.getAutofillId())
+ .assertViewAppeared(s3c3, rootId)
+ .assertViewTreeFinished();
final Session childTestSession4 = service.getFinishedSession(childSessionId4);
assertChildSessionContext(childTestSession4, "session4");
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
index 74429de..ad79e02 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
@@ -15,17 +15,9 @@
*/
package android.contentcaptureservice.cts;
-import static android.contentcaptureservice.cts.Assertions.assertDecorViewAppeared;
import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
-import static android.contentcaptureservice.cts.Assertions.assertSessionPaused;
-import static android.contentcaptureservice.cts.Assertions.assertSessionResumed;
-import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
import static android.contentcaptureservice.cts.Assertions.assertViewTextChanged;
-import static android.contentcaptureservice.cts.Assertions.assertViewTreeFinished;
-import static android.contentcaptureservice.cts.Assertions.assertViewTreeStarted;
-import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
import static android.contentcaptureservice.cts.Assertions.assertVirtualViewAppeared;
-import static android.contentcaptureservice.cts.Assertions.assertVirtualViewDisappeared;
import static android.contentcaptureservice.cts.Assertions.assertVirtualViewsDisappeared;
import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
import static android.contentcaptureservice.cts.Helper.NO_ACTIVITIES;
@@ -149,24 +141,19 @@
Log.v(TAG, "events(" + events.size() + "): " + events);
final int additionalEvents = 2;
- assertThat(events.size()).isAtLeast(CustomViewActivity.MIN_EVENTS + additionalEvents);
-
- // Assert just the relevant events
- assertSessionResumed(events, 0);
- assertViewTreeStarted(events, 1);
- assertDecorViewAppeared(events, 2, decorView);
- assertViewAppeared(events, 3, grandpa2, decorView.getAutofillId());
- assertViewAppeared(events, 4, grandpa1, grandpa2.getAutofillId());
-
- // Assert for session lifecycle events.
- assertSessionResumed(events, 5);
- assertSessionPaused(events, 6);
-
- assertViewWithUnknownParentAppeared(events, 7, session.id, customViewRef.get());
- assertViewTreeFinished(events, 8);
- assertSessionPaused(events, 9);
-
- activity.assertInitialViewsDisappeared(events, additionalEvents);
+ new EventsAssertor(events)
+ .isAtLeast(CustomViewActivity.MIN_EVENTS + additionalEvents)
+ .assertSessionResumed()
+ .assertViewTreeStarted()
+ .assertDecorViewAppeared(decorView)
+ .assertViewAppeared(grandpa2, decorView.getAutofillId())
+ .assertViewAppeared(grandpa1, grandpa2.getAutofillId())
+ // Assert for session lifecycle events.
+ .assertSessionResumed()
+ .assertSessionPaused()
+ .assertViewAppeared(session.id, customViewRef.get())
+ .assertViewTreeFinished()
+ .assertSessionPaused();
}
/**
@@ -218,27 +205,20 @@
final List<ContentCaptureEvent> events = session.getEvents();
Log.v(TAG, "events(" + events.size() + "): " + events);
final int additionalEvents = 2;
-
- assertThat(events.size()).isAtLeast(CustomViewActivity.MIN_EVENTS + additionalEvents);
-
- // Assert just the relevant events
- assertSessionResumed(events, 0);
- assertViewTreeStarted(events, 1);
- assertDecorViewAppeared(events, 2, decorView);
- assertViewAppeared(events, 3, grandpa2, decorView.getAutofillId());
- assertViewAppeared(events, 4, grandpa1, grandpa2.getAutofillId());
-
final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
- assertVirtualViewAppeared(events, 5, mainSession, customViewId, 1, "child");
- assertVirtualViewDisappeared(events, 6, customViewId, mainSession, 1);
- // This is the "wrong" part - the parent is notified last
- assertViewWithUnknownParentAppeared(events, 7, session.id, activity.mCustomView);
-
- assertViewTreeFinished(events, 8);
- assertSessionPaused(events, 9);
-
- activity.assertInitialViewsDisappeared(events, additionalEvents);
+ new EventsAssertor(events)
+ .isAtLeast(CustomViewActivity.MIN_EVENTS + additionalEvents)
+ .assertSessionResumed()
+ .assertViewTreeStarted()
+ .assertDecorViewAppeared(decorView)
+ .assertViewAppeared(grandpa2, decorView.getAutofillId())
+ .assertViewAppeared(grandpa1, grandpa2.getAutofillId())
+ .assertVirtualViewAppeared(mainSession, customViewId, 1, "child")
+ .assertVirtualViewDisappeared(customViewId, mainSession, 1)
+ .assertViewAppeared(session.id, activity.mCustomView)
+ .assertViewTreeFinished()
+ .assertSessionPaused();
}
/**
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/EventsAssertor.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/EventsAssertor.java
new file mode 100644
index 0000000..d00b031
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/EventsAssertor.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2021 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.contentcaptureservice.cts;
+
+import static android.contentcaptureservice.cts.Assertions.assertSessionId;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.autofill.AutofillId;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ContentCaptureSession;
+import android.view.contentcapture.ContentCaptureSessionId;
+import android.view.contentcapture.ViewNode;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Used to assert Content Capture events by the event order.
+ *
+ * When the type is the same, the assertor will assert the content of the event.
+ * If the current event is different type, this event will be skipped, and then
+ * try to assert the next event. Through all events, the assertor will report an
+ * "not found" error.
+ */
+public class EventsAssertor {
+ private static final String TAG = "CtsContentCapture";
+ private final List<ContentCaptureEvent> mEvents;
+ private int mNextEvent = 0;
+
+ public EventsAssertor(@NonNull List<ContentCaptureEvent> events) {
+ mEvents = Collections.unmodifiableList(events);
+ }
+
+ @NonNull
+ public EventsAssertor isAtLeast(int size) {
+ assertThat(mEvents.size()).isAtLeast(size);
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_SESSION_RESUMED} event.
+ */
+ @NonNull
+ public EventsAssertor assertSessionResumed() {
+ assertNextEvent((event) -> assertSessionLevelEvent(event),
+ ContentCaptureEvent.TYPE_SESSION_RESUMED, "no SESSION_RESUMED event");
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_SESSION_PAUSED} event.
+ */
+ @NonNull
+ public EventsAssertor assertSessionPaused() {
+ assertNextEvent((event) -> assertSessionLevelEvent(event),
+ ContentCaptureEvent.TYPE_SESSION_PAUSED, "no SESSION_PAUSED event");
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_TREE_APPEARING} event.
+ */
+ @NonNull
+ public EventsAssertor assertViewTreeStarted() {
+ assertNextEvent((event) -> assertSessionLevelEvent(event),
+ ContentCaptureEvent.TYPE_VIEW_TREE_APPEARING, "no VIEW_TREE_APPEARING event");
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_TREE_APPEARED} event.
+ */
+ @NonNull
+ public EventsAssertor assertViewTreeFinished() {
+ assertNextEvent((event) -> assertSessionLevelEvent(event),
+ ContentCaptureEvent.TYPE_VIEW_TREE_APPEARED,
+ "no VIEW_TREE_APPEARED event");
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_APPEARED}
+ * event for a decor view.
+ *
+ * <P>The decor view is typically internal, so there isn't much we can assert,
+ * other than its autofill id.
+ */
+ @NonNull
+ public EventsAssertor assertDecorViewAppeared(@NonNull View expectedDecorView) {
+ assertNextEvent((event) -> assertEventId(event, expectedDecorView),
+ ContentCaptureEvent.TYPE_VIEW_APPEARED,
+ "no VIEW_APPEARED event for decor view");
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_APPEARED}
+ * event, without checking for parent id.
+ */
+ @NonNull
+ public EventsAssertor assertViewAppeared(@NonNull View expectedView) {
+ assertNextEvent((event) -> assertViewEvent(event, expectedView),
+ ContentCaptureEvent.TYPE_VIEW_APPEARED,
+ String.format("no VIEW_APPEARED event for %s", expectedView));
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_APPEARED} event.
+ */
+ @NonNull
+ public EventsAssertor assertViewAppeared(@NonNull View expectedView,
+ @NonNull AutofillId expectedParentId) {
+ assertNextEvent((event) -> assertViewEvent(event, expectedView, expectedParentId),
+ ContentCaptureEvent.TYPE_VIEW_APPEARED,
+ String.format("no VIEW_APPEARED event for %s", expectedView));
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_APPEARED} event.
+ */
+ @NonNull
+ public EventsAssertor assertViewAppeared(@NonNull ContentCaptureSessionId expectedSessionId,
+ @NonNull View expectedView, @NonNull AutofillId expectedParentId) {
+ assertViewAppeared(expectedView, expectedParentId);
+ assertSessionId(expectedSessionId, expectedView);
+ return this;
+ }
+
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_APPEARED} event.
+ */
+ @NonNull
+ public EventsAssertor assertViewAppeared(@NonNull ContentCaptureSessionId expectedSessionId,
+ @NonNull View expectedView) {
+ assertViewAppeared(expectedView);
+ assertSessionId(expectedSessionId, expectedView);
+ return this;
+ }
+
+ /**
+ * Asserts the {@code text} of a {@link ContentCaptureEvent#TYPE_VIEW_APPEARED}
+ * event.
+ */
+ @NonNull
+ public EventsAssertor assertViewAppeared(@NonNull String text) {
+ assertNextEvent((event) -> assertEventText(event, text),
+ ContentCaptureEvent.TYPE_VIEW_APPEARED,
+ String.format("no TYPE_VIEW_APPEARED event with text: %s", text));
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_DISAPPEARED}
+ * event for multiple views.
+ */
+ @NonNull
+ public EventsAssertor assertViewDisappeared(@NonNull AutofillId autofillId) {
+ assertNextEvent((event) -> assertDisappearedEvent(event, autofillId),
+ ContentCaptureEvent.TYPE_VIEW_DISAPPEARED,
+ String.format("no VIEW_DISAPPEARED event for %s", autofillId));
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_DISAPPEARED}
+ * event for multiple views.
+ */
+ @NonNull
+ public EventsAssertor assertViewDisappeared(@NonNull AutofillId... autofillIds) {
+ assertNextEvent((event) -> assertDisappearedEvent(event, autofillIds),
+ ContentCaptureEvent.TYPE_VIEW_DISAPPEARED,
+ String.format("no VIEW_DISAPPEARED event for %s", Arrays.toString(autofillIds)));
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_APPEARED}
+ * event for a virtual node.
+ */
+ @NonNull
+ public EventsAssertor assertVirtualViewAppeared(@NonNull ContentCaptureSession session,
+ @NonNull AutofillId parentId, int childId, String expectedText) {
+ final AutofillId expectedId = session.newAutofillId(parentId, childId);
+ assertNextEvent((event) -> assertVirtualViewEvent(event, expectedId, expectedText),
+ ContentCaptureEvent.TYPE_VIEW_APPEARED,
+ String.format("no VIEW_APPEARED event for %s", expectedId.toString()));
+ return this;
+ }
+
+ /**
+ * Asserts the contents of a {@link ContentCaptureEvent#TYPE_VIEW_DISAPPEARED}
+ * event for a virtual node.
+ */
+ @NonNull
+ public EventsAssertor assertVirtualViewDisappeared(AutofillId parentId,
+ ContentCaptureSession session, int childId) {
+ return assertViewDisappeared(session.newAutofillId(parentId, childId));
+ }
+
+ @Nullable
+ private String assertVirtualViewEvent(@NonNull ContentCaptureEvent event,
+ @NonNull AutofillId expectedId, @Nullable String expectedText) {
+ final ViewNode node = event.getViewNode();
+ assertThat(node).isNotNull();
+ assertWithMessage("wrong autofill id on %s", event)
+ .that(node.getAutofillId()).isEqualTo(expectedId);
+ if (expectedText != null) {
+ assertWithMessage("wrong text on %s", event)
+ .that(node.getText().toString()).isEqualTo(expectedText);
+ } else {
+ assertWithMessage("%s should not have text", node)
+ .that(node.getText()).isNull();
+ }
+ return null;
+ }
+
+ @Nullable
+ private String assertDisappearedEvent(@NonNull ContentCaptureEvent event,
+ @NonNull AutofillId expectedId) {
+ assertCommonViewDisappearedProperties(event);
+ assertWithMessage("wrong autofillId on event %s", event)
+ .that(event.getId()).isEqualTo(expectedId);
+ assertWithMessage("event %s should not have autofillIds", event)
+ .that(event.getIds()).isNull();
+ return null;
+ }
+
+ @Nullable
+ private String assertDisappearedEvent(@NonNull ContentCaptureEvent event,
+ @NonNull AutofillId[] expectedIds) {
+ final List<AutofillId> ids = event.getIds();
+
+ assertCommonViewDisappearedProperties(event);
+ assertWithMessage("no autofillIds on event %s", event).that(ids)
+ .isNotNull();
+ assertWithMessage("wrong autofillId on event %s", event)
+ .that(ids).containsExactly((Object[]) expectedIds).inOrder();
+ assertWithMessage("event %s should not have autofillId", event)
+ .that(event.getId()).isNull();
+ return null;
+ }
+
+ private void assertCommonViewDisappearedProperties(@NonNull ContentCaptureEvent event) {
+ assertWithMessage("event %s should not have a ViewNode", event)
+ .that(event.getViewNode()).isNull();
+ assertWithMessage("event %s should not have text", event)
+ .that(event.getText()).isNull();
+ }
+
+ @Nullable
+ private String assertViewEvent(@NonNull ContentCaptureEvent event, @NonNull View expectedView) {
+ return assertViewEvent(event, expectedView, /* expectedParentId */ null);
+ }
+
+ @Nullable
+ private String assertViewEvent(@NonNull ContentCaptureEvent event, @NonNull View expectedView,
+ @Nullable AutofillId expectedParentId) {
+ assertEvent(event, expectedView, expectedParentId, /* expectedText */ null);
+ return null;
+ }
+
+ @Nullable
+ private String assertViewEvent(@NonNull ContentCaptureEvent event, @NonNull View expectedView,
+ AutofillId expectedParentId, String expectedText) {
+ assertEvent(event, expectedView, expectedParentId, expectedText);
+ return null;
+ }
+
+ private String assertEventId(@NonNull ContentCaptureEvent event, View expectedView) {
+ final ViewNode node = event.getViewNode();
+
+ if (node == null) {
+ return String.format("node is null at %s", event);
+ }
+
+ if (expectedView != null && !node.getAutofillId().equals(expectedView.getAutofillId())) {
+ return String.format("wrong event id (expected %s, actual is %s) at %s",
+ expectedView.getAutofillId(), node.getAutofillId(), event);
+ }
+ return null;
+ }
+
+ private String assertEventText(@NonNull ContentCaptureEvent event, String expectedText) {
+ final ViewNode node = event.getViewNode();
+ if (node == null) {
+ return String.format("node is null at %s", event);
+ }
+
+ if (!TextUtils.equals(node.getText(), expectedText)) {
+ return String.format("wrong event text (expected %s, actual is %s) at %s",
+ expectedText, node.getText(), event);
+ }
+ return null;
+ }
+
+ private void assertEvent(@NonNull ContentCaptureEvent event, @Nullable View expectedView,
+ @Nullable AutofillId expectedParentId, @Nullable String expectedText) {
+ final ViewNode node = event.getViewNode();
+
+ assertThat(node).isNotNull();
+ assertWithMessage("wrong class on %s", event).that(node.getClassName())
+ .isEqualTo(expectedView.getClass().getName());
+ assertWithMessage("wrong autofill id on %s", event).that(node.getAutofillId())
+ .isEqualTo(expectedView.getAutofillId());
+
+ if (expectedParentId != null) {
+ assertWithMessage("wrong parent autofill id on %s", event)
+ .that(node.getParentAutofillId()).isEqualTo(expectedParentId);
+ }
+
+ if (expectedText != null) {
+ assertWithMessage("wrong text on %s", event).that(node.getText().toString())
+ .isEqualTo(expectedText);
+ }
+ }
+
+ @Nullable
+ private String assertSessionLevelEvent(@NonNull ContentCaptureEvent event) {
+ assertWithMessage("event %s should not have a ViewNode", event)
+ .that(event.getViewNode()).isNull();
+ assertWithMessage("event %s should not have text", event)
+ .that(event.getText()).isNull();
+ assertWithMessage("event %s should not have an autofillId", event)
+ .that(event.getId()).isNull();
+ assertWithMessage("event %s should not have autofillIds", event)
+ .that(event.getIds()).isNull();
+ return null;
+ }
+
+ private void assertNextEvent(@NonNull EventAssertion assertion, int expectedType,
+ @NonNull String errorFormat, @Nullable Object... errorArgs) {
+ if (mNextEvent >= mEvents.size()) {
+ throw new AssertionError("Reached the end of the events: "
+ + String.format(errorFormat, errorArgs) + "\n. Events("
+ + mEvents.size() + "): " + mEvents);
+ }
+ do {
+ final int index = mNextEvent++;
+ final ContentCaptureEvent event = mEvents.get(index);
+ if (event.getType() != expectedType) {
+ Log.w(TAG, "assertNextEvent(): ignoring event #" + index + "(" + event + ")");
+ continue;
+ }
+ // If returns an error message from getErrorMessage(), means the error can be ignored.
+ // The test will assert nex event.
+ // If directly throws AssertionError or exception, means the error cannot be ignored.
+ // The test will stop immediately.
+ final String error = assertion.getErrorMessage(event);
+ if (error == null) {
+ Log.d(TAG, "assertNextEvent(): match event in #" + index + ".");
+ return;
+ }
+ Log.w(TAG, "assertNextEvent(): ignoring event #" + index + "(" + event + "): "
+ + error);
+ } while (mNextEvent < mEvents.size());
+ throw new AssertionError(String.format(errorFormat, errorArgs) + "\n. Events("
+ + mEvents.size() + "): " + mEvents);
+ }
+
+ private interface EventAssertion {
+ @Nullable
+ String getErrorMessage(@NonNull ContentCaptureEvent event);
+ }
+}
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
index 35893a7..b2dbbd4 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
@@ -233,6 +233,7 @@
@Test
public void testSimpleBiometricAuth_convenience() throws Exception {
+ assumeTrue(Utils.isFirstApiLevel29orGreater());
for (SensorProperties props : mSensorProperties) {
if (props.getSensorStrength() != SensorProperties.STRENGTH_CONVENIENCE) {
continue;
diff --git a/tests/framework/base/windowmanager/AndroidManifest.xml b/tests/framework/base/windowmanager/AndroidManifest.xml
index 4827246..210de2b 100644
--- a/tests/framework/base/windowmanager/AndroidManifest.xml
+++ b/tests/framework/base/windowmanager/AndroidManifest.xml
@@ -350,6 +350,7 @@
android:configChanges="orientation|screenLayout|keyboard|keyboardHidden|navigation"
android:showWhenLocked="true"/>
<activity android:name="android.server.wm.WindowInsetsPolicyTest$TestActivity"
+ android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:turnScreenOn="true"
android:showWhenLocked="true"/>
<activity android:name="android.server.wm.WindowInsetsPolicyTest$FullscreenTestActivity"/>
@@ -357,8 +358,6 @@
<activity android:name="android.server.wm.WindowInsetsPolicyTest$ImmersiveFullscreenTestActivity"
android:documentLaunchMode="always"
android:theme="@style/no_animation"/>
- <activity android:name="android.server.wm.WindowInsetsPolicyTest$NaturalOrientationTestActivity"
- android:screenOrientation="nosensor"/>
<activity android:name="android.server.wm.LayoutTests$TestActivity"
android:theme="@style/no_animation"/>
<activity android:name="android.server.wm.LocationOnScreenTests$TestActivity"
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTestsActivity.java b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTestsActivity.java
index c051817..a4f62fe 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTestsActivity.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/AlertWindowsAppOpsTestsActivity.java
@@ -35,14 +35,14 @@
}
public void hideSystemAlertWindow() {
- getWindowManager().removeView(mContent);
+ if (mContent != null && mContent.isAttachedToWindow()) {
+ getWindowManager().removeView(mContent);
+ }
}
@Override
protected void onDestroy() {
super.onDestroy();
- if (mContent != null) {
- hideSystemAlertWindow();
- }
+ hideSystemAlertWindow();
}
}
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
index b49e726..3bd2479 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/SplashscreenTests.java
@@ -152,18 +152,6 @@
testSplashScreenColor(SPLASHSCREEN_ACTIVITY, Color.BLUE, Color.WHITE);
}
- @Test
- public void testSplashscreenContent_FreeformWindow() {
- // TODO(b/192431448): Allow Automotive to skip this test until Splash Screen is properly
- // applied insets by system bars in AAOS.
- assumeFalse(isCar());
- assumeTrue(supportsFreeform());
-
- launchActivityNoWait(SPLASHSCREEN_ACTIVITY, WINDOWING_MODE_FREEFORM);
- // The windowSplashScreenContent attribute is set to RED. We check that it is ignored.
- testSplashScreenColor(SPLASHSCREEN_ACTIVITY, Color.BLUE, Color.WHITE);
- }
-
private void testSplashScreenColor(ComponentName name, int primaryColor, int secondaryColor) {
// Activity may not be launched yet even if app transition is in idle state.
mWmState.waitForActivityState(name, STATE_RESUMED);
@@ -411,18 +399,6 @@
}
@Test
- public void testSetBackgroundColorActivity_FreeformWindow() {
- // TODO(b/192431448): Allow Automotive to skip this test until Splash Screen is properly
- // applied insets by system bars in AAOS.
- assumeFalse(isCar());
- assumeTrue(supportsFreeform());
-
- launchActivityNoWait(SPLASH_SCREEN_REPLACE_ICON_ACTIVITY, WINDOWING_MODE_FREEFORM,
- extraBool(DELAY_RESUME, true));
- testSplashScreenColor(SPLASH_SCREEN_REPLACE_ICON_ACTIVITY, Color.BLUE, Color.WHITE);
- }
-
- @Test
public void testHandleExitIconAnimatingActivity() throws Exception {
assumeFalse(isLeanBack());
final CommandSession.ActivitySession homeActivity = prepareTestLauncher();
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
index 1ba6672..6552273 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/StartActivityTests.java
@@ -171,6 +171,7 @@
getLaunchActivityBuilder()
.setTargetActivity(LAUNCHING_ACTIVITY)
.setUseInstrumentation()
+ .setWaitForLaunched(false)
.execute();
// make sure TEST_ACTIVITY is still on top and resumed
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsPolicyTest.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsPolicyTest.java
index a3b504e..ab057d7 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsPolicyTest.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowInsetsPolicyTest.java
@@ -18,8 +18,8 @@
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.server.wm.app.Components.LAUNCHING_ACTIVITY;
-import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_90;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -88,11 +88,6 @@
new ActivityTestRule<>(ImmersiveFullscreenTestActivity.class,
false /* initialTouchMode */, false /* launchActivity */);
- @Rule
- public final ActivityTestRule<NaturalOrientationTestActivity> mNaturalOrientationTestActivity =
- new ActivityTestRule<>(NaturalOrientationTestActivity.class,
- false /* initialTouchMode */, false /* launchActivity */);
-
@Before
@Override
public void setUp() throws Exception {
@@ -129,16 +124,20 @@
assumeTrue("Skipping test: no split multi-window support",
supportsSplitScreenMultiWindow());
- launchAndWait(mNaturalOrientationTestActivity);
- mWmState.computeState(new ComponentName[] {});
- final boolean naturalOrientationPortrait =
- mWmState.getDisplay(DEFAULT_DISPLAY)
- .mFullConfiguration.orientation == ORIENTATION_PORTRAIT;
-
- final RotationSession rotationSession = createManagedRotationSession();
- rotationSession.set(naturalOrientationPortrait ? ROTATION_90 : ROTATION_0);
-
final TestActivity activity = launchAndWait(mTestActivity);
+ final int rotation = activity.getDisplay().getRotation();
+ final boolean isPortrait = activity.getResources().getConfiguration()
+ .orientation == ORIENTATION_PORTRAIT;
+ final RotationSession rotationSession = createManagedRotationSession();
+ if (isPortrait) {
+ // Rotate to landscape.
+ rotationSession.set(rotation == ROTATION_0 || rotation == ROTATION_180
+ ? ROTATION_90 : ROTATION_0);
+ } else {
+ // Keep in landscape.
+ rotationSession.set(rotation);
+ }
+
mWmState.waitForValidState(mTestActivityComponentName);
final int taskId = mWmState.getTaskByActivity(mTestActivityComponentName).mTaskId;
launchActivityInPrimarySplit(LAUNCHING_ACTIVITY);
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
index c656d22..6218e31 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowMetricsActivityTests.java
@@ -47,6 +47,7 @@
import androidx.test.filters.FlakyTest;
import org.junit.Test;
+import java.util.function.Supplier;
/**
* Tests that verify the behavior of {@link WindowMetrics} APIs on {@link Activity activities}.
@@ -203,7 +204,6 @@
// Resize the freeform activity.
resizeActivityTask(activity.getComponentName(), WINDOW_BOUNDS.left, WINDOW_BOUNDS.top,
WINDOW_BOUNDS.right, WINDOW_BOUNDS.bottom);
- mWmState.computeState(activity.getComponentName());
assertMetricsMatchesLayout(activity);
@@ -211,7 +211,6 @@
resizeActivityTask(activity.getComponentName(), RESIZED_WINDOW_BOUNDS.left,
RESIZED_WINDOW_BOUNDS.top, RESIZED_WINDOW_BOUNDS.right,
RESIZED_WINDOW_BOUNDS.bottom);
- mWmState.computeState(activity.getComponentName());
assertMetricsMatchesLayout(activity);
@@ -219,7 +218,6 @@
resizeActivityTask(activity.getComponentName(), MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.left,
MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.top, MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.right,
MOVE_OFFSET + RESIZED_WINDOW_BOUNDS.bottom);
- mWmState.computeState(activity.getComponentName());
assertMetricsMatchesLayout(activity);
}
@@ -261,19 +259,21 @@
final OnLayoutChangeListener listener = activity.mListener;
listener.waitForLayout();
- final WindowMetrics currentMetrics = activity.getWindowManager().getCurrentWindowMetrics();
- final WindowMetrics maxMetrics = activity.getWindowManager().getMaximumWindowMetrics();
+ final Supplier<WindowMetrics> currentMetrics =
+ () -> activity.getWindowManager().getCurrentWindowMetrics();
+ final Supplier<WindowMetrics> maxMetrics =
+ () -> activity.getWindowManager().getMaximumWindowMetrics();
Condition.waitFor(new Condition<>("WindowMetrics must match layout metrics",
- () -> currentMetrics.getBounds().equals(listener.getLayoutBounds()))
+ () -> currentMetrics.get().getBounds().equals(listener.getLayoutBounds()))
.setRetryIntervalMs(500).setRetryLimit(10)
.setOnFailure(unused -> fail("WindowMetrics must match layout metrics. Layout"
+ "bounds is" + listener.getLayoutBounds() + ", while current window"
- + "metrics is " + currentMetrics.getBounds())));
+ + "metrics is " + currentMetrics.get().getBounds())));
final boolean isFreeForm = activity.getResources().getConfiguration().windowConfiguration
.getWindowingMode() == WINDOWING_MODE_FREEFORM;
- WindowMetricsTestHelper.assertMetricsMatchesLayout(currentMetrics, maxMetrics,
+ WindowMetricsTestHelper.assertMetricsMatchesLayout(currentMetrics.get(), maxMetrics.get(),
listener.getLayoutBounds(), listener.getLayoutInsets(), isFreeForm);
}
diff --git a/tests/inputmethod/src/android/view/inputmethod/cts/SpellCheckerTest.kt b/tests/inputmethod/src/android/view/inputmethod/cts/SpellCheckerTest.kt
index 2c2eb9f..110f9d0 100644
--- a/tests/inputmethod/src/android/view/inputmethod/cts/SpellCheckerTest.kt
+++ b/tests/inputmethod/src/android/view/inputmethod/cts/SpellCheckerTest.kt
@@ -424,8 +424,9 @@
MockSpellCheckerClient.create(context, configuration).use {
val (activity, editText) = startTestActivity()
CtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, editText)
- waitOnMainUntil({ editText.hasFocus() }, TIMEOUT)
val imm = activity.getSystemService(InputMethodManager::class.java)
+ waitOnMainUntil({ editText.hasFocus() &&
+ imm.hasActiveInputConnection(editText) }, TIMEOUT)
assertThat(imm?.isInputMethodSuppressingSpellChecker).isTrue()
// SpellCheckerSession should return empty results if suppressed.
@@ -451,8 +452,9 @@
val (activity, editText) = startTestActivity()
CtsTouchUtils.emulateTapOnViewCenter(instrumentation, null, editText)
- waitOnMainUntil({ editText.hasFocus() }, TIMEOUT)
val imm = activity.getSystemService(InputMethodManager::class.java)
+ waitOnMainUntil({ editText.hasFocus() &&
+ imm.hasActiveInputConnection(editText) }, TIMEOUT)
assertThat(imm?.isInputMethodSuppressingSpellChecker).isFalse()
}
}
diff --git a/tests/jdwp/AndroidTest.xml b/tests/jdwp/AndroidTest.xml
index d17adbd..c0b6bfc 100644
--- a/tests/jdwp/AndroidTest.xml
+++ b/tests/jdwp/AndroidTest.xml
@@ -37,8 +37,8 @@
<option name="dalvik-arg" value="--debuggable" />
<option name="dalvik-arg" value="-Xusejit:true" />
<option name="dalvik-arg" value="-Djpda.settings.verbose=false" />
- <option name="dalvik-arg" value="-Djpda.settings.timeout=10000" />
- <option name="dalvik-arg" value="-Djpda.settings.waitingTime=10000" />
+ <option name="dalvik-arg" value="-Djpda.settings.timeout=20000" />
+ <option name="dalvik-arg" value="-Djpda.settings.waitingTime=20000" />
<option name="dalvik-arg" value="-Djpda.settings.dumpProcess='/system/xbin/su root /system/bin/logwrapper /system/bin/debuggerd'" />
<option name="dalvik-arg-adbconnection" value="-Djpda.settings.debuggeeAgentArgument=-agentpath:" />
<option name="dalvik-arg-adbconnection" value="-Djpda.settings.debuggeeAgentName=libjdwp.so" />
diff --git a/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java b/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java
index 1e9d3b4..ee9a713 100644
--- a/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java
+++ b/tests/location/common/src/android/location/cts/common/TestMeasurementUtil.java
@@ -367,12 +367,6 @@
"X > 0.0",
String.valueOf(correlationVector.getSamplingWidthMeters()),
correlationVector.getSamplingWidthMeters() > 0.0);
- softAssert.assertTrue("frequency_offset_mps : "
- + "Offset of the first sampling bin in meters",
- timeInNs,
- "X >= 0.0",
- String.valueOf(correlationVector.getSamplingStartMeters()),
- correlationVector.getSamplingStartMeters() >= 0.0);
softAssert.assertTrue("Magnitude count",
timeInNs,
"X > 0",
diff --git a/tests/location/location_privileged/src/android/location/cts/privileged/GnssMeasurementTest.java b/tests/location/location_privileged/src/android/location/cts/privileged/GnssMeasurementTest.java
index 00c6770..d0be114 100644
--- a/tests/location/location_privileged/src/android/location/cts/privileged/GnssMeasurementTest.java
+++ b/tests/location/location_privileged/src/android/location/cts/privileged/GnssMeasurementTest.java
@@ -106,7 +106,7 @@
correlationVectors.add(
new CorrelationVector.Builder()
.setSamplingWidthMeters(30d)
- .setSamplingStartMeters(20d)
+ .setSamplingStartMeters(-20d)
.setFrequencyOffsetMetersPerSecond(20d)
.setMagnitude(new int[] {0, 3000, 5000, 3000, 0, 0, 1000, 0})
.build());
diff --git a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
index e493dcd..431425f 100644
--- a/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
+++ b/tests/mediapc/src/android/mediapc/cts/PerformanceClassTest.java
@@ -74,7 +74,7 @@
// Verify minimum screen density and resolution
assertMinDpiAndPixels(context, DENSITY_400, 1920, 1080);
// Verify minimum memory
- assertMinMemoryMb(context, 6 * 1024);
+ assertMinMemoryMb(context, 5 * 1024);
}
}
diff --git a/tests/sensor/src/android/hardware/cts/helpers/SensorRatePermissionEventConnectionTestHelper.java b/tests/sensor/src/android/hardware/cts/helpers/SensorRatePermissionEventConnectionTestHelper.java
index 5094d17..952faab 100644
--- a/tests/sensor/src/android/hardware/cts/helpers/SensorRatePermissionEventConnectionTestHelper.java
+++ b/tests/sensor/src/android/hardware/cts/helpers/SensorRatePermissionEventConnectionTestHelper.java
@@ -36,7 +36,7 @@
* A helper class to test sensor APIs related to sampling rates of SensorEventConnections.
*/
public class SensorRatePermissionEventConnectionTestHelper {
- public static final int CAPPED_SAMPLE_RATE_HZ = 220; // Capped rate 200 Hz + 10% headroom
+ public static final int CAPPED_SAMPLE_RATE_HZ = 270; // Capped rate 200 Hz + 10% headroom
// Set of sensors that are throttled
public static final ImmutableSet<Integer> CAPPED_SENSOR_TYPE_SET = ImmutableSet.of(
Sensor.TYPE_ACCELEROMETER,
diff --git a/tests/signature/api-check/Android.bp b/tests/signature/api-check/Android.bp
index 5e7ff3b..96f3a9a 100644
--- a/tests/signature/api-check/Android.bp
+++ b/tests/signature/api-check/Android.bp
@@ -53,6 +53,18 @@
compile_multilib: "both",
}
+// Defaults for signature api checks with dynamic config.
+java_defaults {
+ name: "signature-api-check-dynamic-config-defaults",
+ defaults: ["signature-api-check-defaults"],
+ defaults_visibility: [
+ "//cts/tests/signature:__subpackages__",
+ ],
+ static_libs: [
+ "cts-signature-with-dynamic-config",
+ ],
+}
+
// Defaults for hiddenapi killswitch checks.
java_defaults {
name: "hiddenapi-killswitch-check-defaults",
@@ -80,7 +92,7 @@
// Defaults for hiddenapi blocklist checks.
java_defaults {
name: "hiddenapi-blocklist-check-defaults",
- defaults: ["signature-api-check-defaults"],
+ defaults: ["signature-api-check-dynamic-config-defaults"],
java_resources: [
":platform-bootclasspath{hiddenapi-flags.csv}",
":cts-api-hiddenapi-filter-csv"
@@ -89,3 +101,12 @@
"libcts_dexchecker",
],
}
+
+// The CtsHiddenApiBlocklistApiDynamicConfig file is intended to be used by
+// multiple CtsHiddenApiBlocklist...TestCases.
+filegroup {
+ name: "CtsHiddenApiBlocklistApiDynamicConfig",
+ srcs: [
+ "CtsHiddenApiBlocklistApiDynamicConfig.dynamic",
+ ],
+}
diff --git a/tests/signature/api-check/CtsHiddenApiBlocklistApiDynamicConfig.dynamic b/tests/signature/api-check/CtsHiddenApiBlocklistApiDynamicConfig.dynamic
new file mode 100644
index 0000000..6dd8025
--- /dev/null
+++ b/tests/signature/api-check/CtsHiddenApiBlocklistApiDynamicConfig.dynamic
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<dynamicConfig>
+ <entry key ="expected_failures">
+ <!--
+ ! Each value in this section identifies an expected failure and is of the
+ ! form:
+ ! <failure-type>:<signature of class/member>
+ !
+ ! These entries are loaded by AnnotationTest which uses them to construct
+ ! an ExpectedFailuresFilter which discards them.
+ !
+ ! e.g. If the test fails with the following error message:
+ ! repackaged.junit.framework.AssertionFailedError:
+ ! extra_class: android.media.MediaParceledListSlice Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! extra_class: android.media.MediaFrameworkInitializer Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! extra_interface: android.media.MediaCommunicationManager$SessionCallback Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! extra_class: android.media.MediaTranscodingManager Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! ClassLoader hierarchy
+ !
+ ! The first step is to check that the extra classes are expected (e.g.
+ ! because they have been annotated with the @SystemApi since this version
+ ! of the CTS tests were released and the tests are being run on an
+ ! Android system with a version of the mainline modules that includes
+ ! those changes.
+ !
+ ! If they are not expected then this must be caused by a partner
+ ! inadvertently adding something to the @SystemApi so the correct
+ ! response is for them to stop doing that.
+ !
+ ! If they are expected then additional entries should be added to this
+ ! section. That simply requires copying each error message into their own
+ ! <value></value> element and then removing the whitespace after the
+ ! first : and also removing the trailing " Error: ..." part (including
+ ! the leading white space).
+ !
+ ! See below for some examples.
+ !-->
+ <!-- Bug: 204723907 -->
+ <value>extra_field:int android.net.wifi.ScanResult.UNSPECIFIED</value>
+ <value>extra_method:boolean android.net.wifi.WifiInfo.isTrusted()</value>
+ <value>extra_method:long[] android.net.wifi.hotspot2.pps.HomeSp.getMatchAllOis()</value>
+ <value>extra_method:long[] android.net.wifi.hotspot2.pps.HomeSp.getMatchAnyOis()</value>
+ <value>extra_method:void android.net.wifi.hotspot2.pps.HomeSp.setMatchAllOis(long[])</value>
+ <value>extra_method:void android.net.wifi.hotspot2.pps.HomeSp.setMatchAnyOis(long[])</value>
+ <!--
+ ! Add any new entries before this.
+ !
+ ! Note: Due to limitations within the build changes to this file it is
+ ! necessary to build CtsHiddenApiBlacklistCurrentApiTestCases in order
+ ! for changes to this file to take effect.
+ !-->
+ </entry>
+</dynamicConfig>
diff --git a/tests/signature/api-check/hidden-api-blocklist-27-api/Android.bp b/tests/signature/api-check/hidden-api-blocklist-27-api/Android.bp
index 86cb1ee..e9f7d7b 100644
--- a/tests/signature/api-check/hidden-api-blocklist-27-api/Android.bp
+++ b/tests/signature/api-check/hidden-api-blocklist-27-api/Android.bp
@@ -28,4 +28,12 @@
"cts",
"general-tests",
],
+ // Ideally the following should be uncommented but unfortunately due to
+ // limitations in the build that causes build failures due to duplicate copy
+ // rules being generated. In the meantime it is necessary to build
+ // CtsHiddenApiBlacklistCurrentApiTestCases before running this test to
+ // pick up any changes to CtsHiddenApiBlocklistApiDynamicConfig.dynamic.
+ // data: [
+ // ":CtsHiddenApiBlocklistApiDynamicConfig",
+ // ],
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-27-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blocklist-27-api/AndroidTest.xml
index fdf5bfa..ac0a3d8 100644
--- a/tests/signature/api-check/hidden-api-blocklist-27-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blocklist-27-api/AndroidTest.xml
@@ -16,8 +16,13 @@
<configuration description="Config for CTS Hidden API Signature test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="systems" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+ <option name="target" value="device" />
+ <option name="config-filename" value="CtsHiddenApiBlocklistApiDynamicConfig" />
+ <option name="version" value="1.0" />
+ </target_preparer>
<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" />
@@ -27,10 +32,13 @@
<option name="package" value="android.signature.cts.api.hiddenapi_blocklist_api_27" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.api27.HiddenApiTest" />
+ <option name="instrumentation-arg" key="dynamic-config-name" value="CtsHiddenApiBlocklistApiDynamicConfig" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi-flags.csv" />
<option name="instrumentation-arg" key="hiddenapi-test-flags" value="blocked" />
<option name="instrumentation-arg" key="hiddenapi-filter-file" value="hiddenapi-filter.csv" />
<option name="test-api-access" value="false" />
<option name="runtime-hint" value="30s" />
+ <!-- disable isolated storage so tests can access dynamic config stored in /sdcard. -->
+ <option name="isolated-storage" value="false" />
</test>
</configuration>
diff --git a/tests/signature/api-check/hidden-api-blocklist-27-api/src/android/signature/cts/api/api27/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blocklist-27-api/src/android/signature/cts/api/api27/HiddenApiTest.java
index c940aac..13ea0f1 100644
--- a/tests/signature/api-check/hidden-api-blocklist-27-api/src/android/signature/cts/api/api27/HiddenApiTest.java
+++ b/tests/signature/api-check/hidden-api-blocklist-27-api/src/android/signature/cts/api/api27/HiddenApiTest.java
@@ -16,5 +16,7 @@
package android.signature.cts.api.api27;
-public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+import android.signature.cts.api.dynamic.DynamicConfigHiddenApiTest;
+
+public class HiddenApiTest extends DynamicConfigHiddenApiTest {
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-28-api/Android.bp b/tests/signature/api-check/hidden-api-blocklist-28-api/Android.bp
index 7c9f844..562c407 100644
--- a/tests/signature/api-check/hidden-api-blocklist-28-api/Android.bp
+++ b/tests/signature/api-check/hidden-api-blocklist-28-api/Android.bp
@@ -28,4 +28,12 @@
"cts",
"general-tests",
],
+ // Ideally the following should be uncommented but unfortunately due to
+ // limitations in the build that causes build failures due to duplicate copy
+ // rules being generated. In the meantime it is necessary to build
+ // CtsHiddenApiBlacklistCurrentApiTestCases before running this test to
+ // pick up any changes to CtsHiddenApiBlocklistApiDynamicConfig.dynamic.
+ // data: [
+ // ":CtsHiddenApiBlocklistApiDynamicConfig",
+ // ],
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-28-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blocklist-28-api/AndroidTest.xml
index 30d29f0..9a8ba04 100644
--- a/tests/signature/api-check/hidden-api-blocklist-28-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blocklist-28-api/AndroidTest.xml
@@ -16,8 +16,13 @@
<configuration description="Config for CTS Hidden API Signature test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="systems" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+ <option name="target" value="device" />
+ <option name="config-filename" value="CtsHiddenApiBlocklistApiDynamicConfig" />
+ <option name="version" value="1.0" />
+ </target_preparer>
<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" />
@@ -27,10 +32,13 @@
<option name="package" value="android.signature.cts.api.hiddenapi_blocklist_api_28" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.api28.HiddenApiTest" />
+ <option name="instrumentation-arg" key="dynamic-config-name" value="CtsHiddenApiBlocklistApiDynamicConfig" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi-flags.csv" />
<option name="instrumentation-arg" key="hiddenapi-test-flags" value="blocked,max-target-o" />
<option name="instrumentation-arg" key="hiddenapi-filter-file" value="hiddenapi-filter.csv" />
<option name="test-api-access" value="false" />
<option name="runtime-hint" value="30s" />
+ <!-- disable isolated storage so tests can access dynamic config stored in /sdcard. -->
+ <option name="isolated-storage" value="false" />
</test>
</configuration>
diff --git a/tests/signature/api-check/hidden-api-blocklist-28-api/src/android/signature/cts/api/api28/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blocklist-28-api/src/android/signature/cts/api/api28/HiddenApiTest.java
index f85dda3..091a25f 100644
--- a/tests/signature/api-check/hidden-api-blocklist-28-api/src/android/signature/cts/api/api28/HiddenApiTest.java
+++ b/tests/signature/api-check/hidden-api-blocklist-28-api/src/android/signature/cts/api/api28/HiddenApiTest.java
@@ -16,5 +16,7 @@
package android.signature.cts.api.api28;
-public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+import android.signature.cts.api.dynamic.DynamicConfigHiddenApiTest;
+
+public class HiddenApiTest extends DynamicConfigHiddenApiTest {
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-current-api/Android.bp b/tests/signature/api-check/hidden-api-blocklist-current-api/Android.bp
index 67e5742..6c3401b 100644
--- a/tests/signature/api-check/hidden-api-blocklist-current-api/Android.bp
+++ b/tests/signature/api-check/hidden-api-blocklist-current-api/Android.bp
@@ -27,4 +27,7 @@
"cts",
"general-tests",
],
+ data: [
+ ":CtsHiddenApiBlocklistApiDynamicConfig",
+ ],
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-current-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blocklist-current-api/AndroidTest.xml
index 7063418..e503a76 100644
--- a/tests/signature/api-check/hidden-api-blocklist-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blocklist-current-api/AndroidTest.xml
@@ -16,8 +16,13 @@
<configuration description="Config for CTS Hidden API Signature test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="systems" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+ <option name="target" value="device" />
+ <option name="config-filename" value="CtsHiddenApiBlocklistApiDynamicConfig" />
+ <option name="version" value="1.0" />
+ </target_preparer>
<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" />
@@ -27,10 +32,13 @@
<option name="package" value="android.signature.cts.api.hiddenapi_blocklist_current" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.current.HiddenApiTest" />
+ <option name="instrumentation-arg" key="dynamic-config-name" value="CtsHiddenApiBlocklistApiDynamicConfig" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi-flags.csv" />
<option name="instrumentation-arg" key="hiddenapi-test-flags" value="blocked,max-target-o,max-target-p" />
<option name="instrumentation-arg" key="hiddenapi-filter-file" value="hiddenapi-filter.csv" />
<option name="test-api-access" value="false" />
<option name="runtime-hint" value="30s" />
+ <!-- disable isolated storage so tests can access dynamic config stored in /sdcard. -->
+ <option name="isolated-storage" value="false" />
</test>
</configuration>
diff --git a/tests/signature/api-check/hidden-api-blocklist-current-api/src/android/signature/cts/api/current/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blocklist-current-api/src/android/signature/cts/api/current/HiddenApiTest.java
index 34f33fe..7726489 100644
--- a/tests/signature/api-check/hidden-api-blocklist-current-api/src/android/signature/cts/api/current/HiddenApiTest.java
+++ b/tests/signature/api-check/hidden-api-blocklist-current-api/src/android/signature/cts/api/current/HiddenApiTest.java
@@ -16,5 +16,7 @@
package android.signature.cts.api.current;
-public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+import android.signature.cts.api.dynamic.DynamicConfigHiddenApiTest;
+
+public class HiddenApiTest extends DynamicConfigHiddenApiTest {
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-debug-class/AndroidTest.xml b/tests/signature/api-check/hidden-api-blocklist-debug-class/AndroidTest.xml
index 2ab58bd..c7df2ee 100644
--- a/tests/signature/api-check/hidden-api-blocklist-debug-class/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blocklist-debug-class/AndroidTest.xml
@@ -16,8 +16,13 @@
<configuration description="Config for CTS Hidden API Signature test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="systems" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+ <option name="target" value="device" />
+ <option name="config-filename" value="CtsHiddenApiBlocklistApiDynamicConfig" />
+ <option name="version" value="1.0" />
+ </target_preparer>
<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" />
@@ -26,11 +31,14 @@
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.signature.cts.api.hiddenapi_blocklist_debug_class" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
- <option name="class" value="android.signature.cts.api.DebugClassHiddenApiTest" />
+ <option name="class" value="android.signature.cts.api.blocklist.debug.DebugClassHiddenApiTest" />
+ <option name="instrumentation-arg" key="dynamic-config-name" value="CtsHiddenApiBlocklistApiDynamicConfig" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi-flags.csv" />
<option name="instrumentation-arg" key="hiddenapi-test-flags" value="blocked,max-target-o,max-target-p" />
<option name="instrumentation-arg" key="hiddenapi-filter-file" value="hiddenapi-filter.csv" />
<option name="test-api-access" value="false" />
<option name="runtime-hint" value="30s" />
+ <!-- disable isolated storage so tests can access dynamic config stored in /sdcard. -->
+ <option name="isolated-storage" value="false" />
</test>
</configuration>
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassHiddenApiTest.java b/tests/signature/api-check/hidden-api-blocklist-debug-class/src/android/signature/cts/api/blocklist/debug/DebugClassHiddenApiTest.java
similarity index 83%
rename from tests/signature/api-check/src/java/android/signature/cts/api/DebugClassHiddenApiTest.java
rename to tests/signature/api-check/hidden-api-blocklist-debug-class/src/android/signature/cts/api/blocklist/debug/DebugClassHiddenApiTest.java
index 8168f08..9266976 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/DebugClassHiddenApiTest.java
+++ b/tests/signature/api-check/hidden-api-blocklist-debug-class/src/android/signature/cts/api/blocklist/debug/DebugClassHiddenApiTest.java
@@ -14,11 +14,12 @@
* limitations under the License.
*/
-package android.signature.cts.api;
+package android.signature.cts.api.blocklist.debug;
import android.signature.cts.DexMemberChecker;
+import android.signature.cts.api.dynamic.DynamicConfigHiddenApiTest;
-public class DebugClassHiddenApiTest extends HiddenApiTest {
+public class DebugClassHiddenApiTest extends DynamicConfigHiddenApiTest {
@Override
protected void setUp() throws Exception {
super.setUp();
diff --git a/tests/signature/api-check/hidden-api-blocklist-test-api/Android.bp b/tests/signature/api-check/hidden-api-blocklist-test-api/Android.bp
index 4ee2db5..d9e8431 100644
--- a/tests/signature/api-check/hidden-api-blocklist-test-api/Android.bp
+++ b/tests/signature/api-check/hidden-api-blocklist-test-api/Android.bp
@@ -26,4 +26,12 @@
"cts",
"general-tests",
],
+ // Ideally the following should be uncommented but unfortunately due to
+ // limitations in the build that causes build failures due to duplicate copy
+ // rules being generated. In the meantime it is necessary to build
+ // CtsHiddenApiBlacklistCurrentApiTestCases before running this test to
+ // pick up any changes to CtsHiddenApiBlocklistApiDynamicConfig.dynamic.
+ // data: [
+ // ":CtsHiddenApiBlocklistApiDynamicConfig",
+ // ],
}
diff --git a/tests/signature/api-check/hidden-api-blocklist-test-api/AndroidTest.xml b/tests/signature/api-check/hidden-api-blocklist-test-api/AndroidTest.xml
index b08abec..1f916fe 100644
--- a/tests/signature/api-check/hidden-api-blocklist-test-api/AndroidTest.xml
+++ b/tests/signature/api-check/hidden-api-blocklist-test-api/AndroidTest.xml
@@ -17,8 +17,13 @@
<configuration description="Config for CTS Hidden API Signature test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="systems" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+ <option name="target" value="device" />
+ <option name="config-filename" value="CtsHiddenApiBlocklistApiDynamicConfig" />
+ <option name="version" value="1.0" />
+ </target_preparer>
<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" />
@@ -28,8 +33,11 @@
<option name="package" value="android.signature.cts.api.hiddenapi_blocklist_test" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.test.HiddenApiTest" />
+ <option name="instrumentation-arg" key="dynamic-config-name" value="CtsHiddenApiBlocklistApiDynamicConfig" />
<option name="instrumentation-arg" key="hiddenapi-files" value="hiddenapi-flags.csv" />
<option name="test-api-access" value="false" />
<option name="runtime-hint" value="30s" />
+ <!-- disable isolated storage so tests can access dynamic config stored in /sdcard. -->
+ <option name="isolated-storage" value="false" />
</test>
</configuration>
diff --git a/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java b/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java
index ffe85fc..3fe708c 100644
--- a/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java
+++ b/tests/signature/api-check/hidden-api-blocklist-test-api/src/android/signature/cts/api/test/HiddenApiTest.java
@@ -17,9 +17,10 @@
package android.signature.cts.api.test;
import android.signature.cts.DexMember;
+import android.signature.cts.api.dynamic.DynamicConfigHiddenApiTest;
import java.util.Set;
-public class HiddenApiTest extends android.signature.cts.api.HiddenApiTest {
+public class HiddenApiTest extends DynamicConfigHiddenApiTest {
/**
* Override to match only those members that specify both test-api and blocked.
diff --git a/tests/signature/api-check/hidden-api-killswitch-sdklist/Android.bp b/tests/signature/api-check/hidden-api-killswitch-sdklist/Android.bp
index 5384558..333a3aa 100644
--- a/tests/signature/api-check/hidden-api-killswitch-sdklist/Android.bp
+++ b/tests/signature/api-check/hidden-api-killswitch-sdklist/Android.bp
@@ -25,4 +25,12 @@
"cts",
"general-tests",
],
+ // Ideally the following should be uncommented but unfortunately due to
+ // limitations in the build that causes build failures due to duplicate copy
+ // rules being generated. In the meantime it is necessary to build
+ // CtsHiddenApiBlacklistCurrentApiTestCases before running this test to
+ // pick up any changes to CtsHiddenApiBlocklistApiDynamicConfig.dynamic.
+ // data: [
+ // ":CtsHiddenApiBlocklistApiDynamicConfig",
+ // ],
}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
index 402c913..8ff6d98 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/AbstractApiTest.java
@@ -39,6 +39,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
+import java.util.List;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
import repackaged.android.test.InstrumentationTestCase;
@@ -54,6 +55,11 @@
ClassProvider mClassProvider;
+ /**
+ * The list of expected failures.
+ */
+ private Collection<String> expectedFailures = Collections.emptyList();
+
protected String getGlobalExemptions() {
return Settings.Global.getString(
getInstrumentation().getContext().getContentResolver(),
@@ -99,6 +105,22 @@
initializeFromArgs(instrumentationArgs);
}
+ /**
+ * Initialize the expected failures.
+ *
+ * <p>Call from with {@code #initializeFromArgs}</p>
+ *
+ * @param expectedFailures the expected failures.
+ */
+ protected void initExpectedFailures(Collection<String> expectedFailures) {
+ this.expectedFailures = expectedFailures;
+ String tag = getClass().getName();
+ Log.d(tag, "Expected failure count: " + expectedFailures.size());
+ for (String failure: expectedFailures) {
+ Log.d(tag, "Expected failure: \"" + failure + "\"");
+ }
+ }
+
protected String getExpectedBlocklistExemptions() {
return null;
}
@@ -112,10 +134,11 @@
}
void runWithTestResultObserver(RunnableWithResultObserver runnable) {
- runWithTestResultObserver(Collections.emptyList(), runnable);
+ runWithTestResultObserver(expectedFailures, runnable);
}
- void runWithTestResultObserver(Collection<String> expectedFailures, RunnableWithResultObserver runnable) {
+ private void runWithTestResultObserver(
+ Collection<String> expectedFailures, RunnableWithResultObserver runnable) {
try {
ResultObserver observer = mResultObserver;
if (!expectedFailures.isEmpty()) {
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
index 3b6fec9..97ae404 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/HiddenApiTest.java
@@ -43,7 +43,7 @@
private Set<String> hiddenapiFilterSet;
@Override
- protected void initializeFromArgs(Bundle instrumentationArgs) {
+ protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
hiddenapiFiles = getCommaSeparatedListRequired(instrumentationArgs, "hiddenapi-files");
hiddenapiTestFlags = getCommaSeparatedListOptional(instrumentationArgs, "hiddenapi-test-flags");
hiddenapiFilterFile = instrumentationArgs.getString("hiddenapi-filter-file");
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
index 316a603..4a0e2c2 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
@@ -42,7 +42,7 @@
private String[] unexpectedApiFiles;
@Override
- protected void initializeFromArgs(Bundle instrumentationArgs) {
+ protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
expectedApiFiles = getCommaSeparatedListOptional(instrumentationArgs, "expected-api-files");
baseApiFiles = getCommaSeparatedListOptional(instrumentationArgs, "base-api-files");
unexpectedApiFiles = getCommaSeparatedListOptional(instrumentationArgs, "unexpected-api-files");
diff --git a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
index e2d71c9..0a3e9b0 100644
--- a/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
+++ b/tests/signature/api-check/system-annotation/src/java/android/signature/cts/api/AnnotationTest.java
@@ -44,7 +44,6 @@
private String[] mExpectedApiFiles;
private String mAnnotationForExactMatch;
- private List<String> expectedFailures;
@Override
protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
@@ -57,11 +56,8 @@
// Get the DynamicConfig.xml contents and extract the expected failures list.
DynamicConfigDeviceSide dcds = new DynamicConfigDeviceSide(MODULE_NAME);
- expectedFailures = dcds.getValues("expected_failures");
- Log.d(TAG, "Expected failure count: " + expectedFailures.size());
- for (String failure: expectedFailures) {
- Log.d(TAG, "Expected failure: \"" + failure + "\"");
- }
+ List<String> expectedFailures = dcds.getValues("expected_failures");
+ initExpectedFailures(expectedFailures);
}
private Predicate<? super JDiffClassDescription> androidAutoClassesFilter() {
@@ -102,7 +98,7 @@
return "android.R$styleable".equals(f.getDeclaringClass().getName());
}
};
- runWithTestResultObserver(expectedFailures, resultObserver -> {
+ runWithTestResultObserver(resultObserver -> {
AnnotationChecker complianceChecker = new AnnotationChecker(resultObserver,
mClassProvider, mAnnotationForExactMatch, filter);
diff --git a/tests/signature/api-check/system-api/Android.mk b/tests/signature/api-check/system-api/Android.mk
index ccb3c58..f4a9b7a 100644
--- a/tests/signature/api-check/system-api/Android.mk
+++ b/tests/signature/api-check/system-api/Android.mk
@@ -46,6 +46,8 @@
LOCAL_PACKAGE_NAME := CtsSystemApiSignatureTestCases
+LOCAL_STATIC_JAVA_LIBRARIES := cts-signature-with-dynamic-config
+
LOCAL_JAVA_RESOURCE_FILES := $(all_system_api_zip_file)
LOCAL_SIGNATURE_API_FILES := \
diff --git a/tests/signature/api-check/system-api/AndroidTest.xml b/tests/signature/api-check/system-api/AndroidTest.xml
index 7c5fb12..179542f 100644
--- a/tests/signature/api-check/system-api/AndroidTest.xml
+++ b/tests/signature/api-check/system-api/AndroidTest.xml
@@ -16,8 +16,13 @@
<configuration description="Config for CTS System API Signature test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="systems" />
- <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.DynamicConfigPusher">
+ <option name="target" value="device" />
+ <option name="config-filename" value="CtsSystemApiSignatureTestCases" />
+ <option name="version" value="1.0" />
+ </target_preparer>
<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" />
@@ -27,12 +32,14 @@
<option name="package" value="android.signature.cts.api.system" />
<option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
<option name="class" value="android.signature.cts.api.system.SignatureTest" />
+ <option name="instrumentation-arg" key="dynamic-config-name" value="CtsSystemApiSignatureTestCases" />
<option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
<option name="instrumentation-arg" key="expected-api-files" value="system-current.api.gz,system-removed.api.gz" />
<option name="instrumentation-arg" key="previous-api-files" value = "system-all.api.zip" />
- <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
<option name="runtime-hint" value="30s" />
<!-- Disable hidden API checks (http://b/171459260). -->
<option name="hidden-api-checks" value="false" />
+ <!-- disable isolated storage so tests can access dynamic config stored in /sdcard. -->
+ <option name="isolated-storage" value="false" />
</test>
</configuration>
diff --git a/tests/signature/api-check/system-api/DynamicConfig.xml b/tests/signature/api-check/system-api/DynamicConfig.xml
new file mode 100644
index 0000000..24aa0bb
--- /dev/null
+++ b/tests/signature/api-check/system-api/DynamicConfig.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<dynamicConfig>
+ <entry key ="expected_failures">
+ <!--
+ ! Each value in this section identifies an expected failure and is of the
+ ! form:
+ ! <failure-type>:<signature of class/member>
+ !
+ ! These entries are loaded by AnnotationTest which uses them to construct
+ ! an ExpectedFailuresFilter which discards them.
+ !
+ ! e.g. If the test fails with the following error message:
+ ! repackaged.junit.framework.AssertionFailedError:
+ ! extra_class: android.media.MediaParceledListSlice Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! extra_class: android.media.MediaFrameworkInitializer Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! extra_interface: android.media.MediaCommunicationManager$SessionCallback Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! extra_class: android.media.MediaTranscodingManager Error: Class annotated with android.annotation.SystemApi does not exist in the documented API
+ ! ClassLoader hierarchy
+ !
+ ! The first step is to check that the extra classes are expected (e.g.
+ ! because they have been annotated with the @SystemApi since this version
+ ! of the CTS tests were released and the tests are being run on an
+ ! Android system with a version of the mainline modules that includes
+ ! those changes.
+ !
+ ! If they are not expected then this must be caused by a partner
+ ! inadvertently adding something to the @SystemApi so the correct
+ ! response is for them to stop doing that.
+ !
+ ! If they are expected then additional entries should be added to this
+ ! section. That simply requires copying each error message into their own
+ ! <value></value> element and then removing the whitespace after the
+ ! first : and also removing the trailing " Error: ..." part (including
+ ! the leading white space).
+ !
+ ! See below for some examples.
+ !-->
+ <!-- Bug: 209335798 -->
+ <value>missing_method:android.bluetooth.BluetoothHeadset#setPriority(android.bluetooth.BluetoothDevice, int)</value>
+ </entry>
+</dynamicConfig>
diff --git a/tests/signature/api-check/system-api/src/android/signature/cts/api/system/SignatureTest.java b/tests/signature/api-check/system-api/src/android/signature/cts/api/system/SignatureTest.java
index 5316e31..e523152 100644
--- a/tests/signature/api-check/system-api/src/android/signature/cts/api/system/SignatureTest.java
+++ b/tests/signature/api-check/system-api/src/android/signature/cts/api/system/SignatureTest.java
@@ -16,5 +16,7 @@
package android.signature.cts.api.system;
-public class SignatureTest extends android.signature.cts.api.SignatureTest {
+import java.android.signature.cts.api.dynamic.DynamicConfigSignatureTest;
+
+public class SignatureTest extends DynamicConfigSignatureTest {
}
diff --git a/tests/signature/api-check/with-dynamic-config/Android.bp b/tests/signature/api-check/with-dynamic-config/Android.bp
new file mode 100644
index 0000000..bdeb878
--- /dev/null
+++ b/tests/signature/api-check/with-dynamic-config/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2021 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.
+
+// Compat.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+ name: "cts-signature-with-dynamic-config",
+ visibility: [
+ "//cts/tests/signature:__subpackages__",
+ ],
+ static_libs: [
+ "cts-api-signature-test",
+ "compatibility-device-util-axt",
+ ],
+ srcs: ["src/java/**/*.java"],
+}
diff --git a/tests/signature/api-check/with-dynamic-config/src/java/android/signature/cts/api/dynamic/DynamicConfigHiddenApiTest.java b/tests/signature/api-check/with-dynamic-config/src/java/android/signature/cts/api/dynamic/DynamicConfigHiddenApiTest.java
new file mode 100644
index 0000000..99f6b7b
--- /dev/null
+++ b/tests/signature/api-check/with-dynamic-config/src/java/android/signature/cts/api/dynamic/DynamicConfigHiddenApiTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2021 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.signature.cts.api.dynamic;
+
+import android.os.Bundle;
+import android.signature.cts.api.HiddenApiTest;
+import android.signature.cts.api.SignatureTest;
+import androidx.test.InstrumentationRegistry;
+import com.android.compatibility.common.util.DynamicConfigDeviceSide;
+import java.util.Collection;
+
+/**
+ * A hidden API test that supports the use of dynamic config.
+ */
+public class DynamicConfigHiddenApiTest extends HiddenApiTest {
+
+ /**
+ * The name of the optional instrumentation option that contains the name of the dynamic config
+ * data set that contains the expected failures.
+ */
+ private static final String DYNAMIC_CONFIG_NAME_OPTION = "dynamic-config-name";
+
+ @Override
+ protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
+ super.initializeFromArgs(instrumentationArgs);
+
+ String dynamicConfigName = instrumentationArgs.getString(DYNAMIC_CONFIG_NAME_OPTION);
+ if (dynamicConfigName != null) {
+ // Make sure that the Instrumentation provided to this test is registered so it can be
+ // retrieved by the DynamicConfigDeviceSide below.
+ InstrumentationRegistry.registerInstance(getInstrumentation(), new Bundle());
+
+ // Get the DynamicConfig.xml contents and extract the expected failures list.
+ DynamicConfigDeviceSide dcds = new DynamicConfigDeviceSide(dynamicConfigName);
+ Collection<String> expectedFailures = dcds.getValues("expected_failures");
+ initExpectedFailures(expectedFailures);
+ }
+ }
+}
diff --git a/tests/signature/api-check/with-dynamic-config/src/java/android/signature/cts/api/dynamic/DynamicConfigSignatureTest.java b/tests/signature/api-check/with-dynamic-config/src/java/android/signature/cts/api/dynamic/DynamicConfigSignatureTest.java
new file mode 100644
index 0000000..8a1e763
--- /dev/null
+++ b/tests/signature/api-check/with-dynamic-config/src/java/android/signature/cts/api/dynamic/DynamicConfigSignatureTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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 java.android.signature.cts.api.dynamic;
+
+import android.os.Bundle;
+import android.signature.cts.api.SignatureTest;
+import androidx.test.InstrumentationRegistry;
+import com.android.compatibility.common.util.DynamicConfigDeviceSide;
+import java.util.Collection;
+
+/**
+ * A signature test that supports the use of dynamic config.
+ */
+public class DynamicConfigSignatureTest extends SignatureTest {
+
+ /**
+ * The name of the optional instrumentation option that contains the name of the dynamic config
+ * data set that contains the expected failures.
+ */
+ private static final String DYNAMIC_CONFIG_NAME_OPTION = "dynamic-config-name";
+
+ @Override
+ protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
+ super.initializeFromArgs(instrumentationArgs);
+
+ String dynamicConfigName = instrumentationArgs.getString(DYNAMIC_CONFIG_NAME_OPTION);
+ if (dynamicConfigName != null) {
+ // Make sure that the Instrumentation provided to this test is registered so it can be
+ // retrieved by the DynamicConfigDeviceSide below.
+ InstrumentationRegistry.registerInstance(getInstrumentation(), new Bundle());
+
+ // Get the DynamicConfig.xml contents and extract the expected failures list.
+ DynamicConfigDeviceSide dcds = new DynamicConfigDeviceSide(dynamicConfigName);
+ Collection<String> expectedFailures = dcds.getValues("expected_failures");
+ initExpectedFailures(expectedFailures);
+ }
+ }
+}
diff --git a/tests/signature/tests/src/android/signature/cts/tests/ExpectedFailuresFilterAnnotationCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/ExpectedFailuresFilterAnnotationCheckerTest.java
index 72a0e27..789d54f 100644
--- a/tests/signature/tests/src/android/signature/cts/tests/ExpectedFailuresFilterAnnotationCheckerTest.java
+++ b/tests/signature/tests/src/android/signature/cts/tests/ExpectedFailuresFilterAnnotationCheckerTest.java
@@ -35,12 +35,12 @@
*/
@RunWith(JUnit4.class)
public class ExpectedFailuresFilterAnnotationCheckerTest
- extends AbstractApiCheckerTest<AnnotationChecker> {
+ extends ApiPresenceCheckerTest<AnnotationChecker> {
@Override
protected AnnotationChecker createChecker(ResultObserver resultObserver,
ClassProvider provider) {
- return new AnnotationChecker(resultObserver, provider, ApiAnnotation.class.getName());
+ return new AnnotationChecker(resultObserver, provider, ApiAnnotation.class.getName(), null);
}
@Test
@@ -69,7 +69,7 @@
@Test
public void testIgnoreExpectedFailures_TestStillFails() {
- NoFailures observer = new NoFailures();
+ ExpectFailure observer = new ExpectFailure(FailureType.MISSING_ANNOTATION);
ResultObserver filter = new ExpectedFailuresFilter(observer, Arrays.asList(
"extra_method:public void android.signature.cts.tests.data.SystemApiClass.apiMethod()",
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index 0e76d36..bf64dbc 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -2260,7 +2260,7 @@
Debug.MemoryInfo meminfoEnd = new Debug.MemoryInfo();
int fdCount = -1;
// Do a warmup to reach steady-state memory usage
- for (int i = 0; i < 50; i++) {
+ for (int i = 0; i < 100; i++) {
test.run();
}
runGcAndFinalizersSync();
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java
index 8fbdd2f..837e3cb 100644
--- a/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanFeaturesTest.java
@@ -327,7 +327,7 @@
}
}
JSONObject limits = device.getJSONObject("properties").getJSONObject("limits");
- int maxPerStageDescriptorStorageBuffers = limits.getInt("maxPerStageDescriptorStorageBuffers");
+ long maxPerStageDescriptorStorageBuffers = limits.getLong("maxPerStageDescriptorStorageBuffers");
if (DEBUG) {
Log.d(TAG, device.getJSONObject("properties").getString("deviceName") +
": variablePointers=" + variablePointers +
diff --git a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
index de60e37..3919f90 100644
--- a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
@@ -43,6 +43,12 @@
private void assertNONEwithECDSATruncatesInputToFieldSize(KeyPair keyPair)
throws Exception {
int keySizeBits = TestUtils.getKeySizeBits(keyPair.getPublic());
+ if (keySizeBits == 521) {
+ /*
+ * Skip P521 test until b/184307265 is fixed.
+ */
+ return;
+ }
byte[] message = new byte[(keySizeBits * 3) / 8];
for (int i = 0; i < message.length; i++) {
message[i] = (byte) (i + 1);
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
index 7d7c56d..730732f 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyAttestationTest.java
@@ -1135,6 +1135,7 @@
assertThat("Attestation version must be >= 1",
attestation.getAttestationVersion(), greaterThanOrEqualTo(1));
+ int firstApiLevel = SystemProperties.getInt("ro.product.first_api_level", 0);
int attestationSecurityLevel = attestation.getAttestationSecurityLevel();
switch (attestationSecurityLevel) {
case KM_SECURITY_LEVEL_STRONG_BOX:
@@ -1145,15 +1146,16 @@
// Devices launched in Android 10.0 (API level 29) and after should run CTS
// in LOCKED state.
- boolean requireLocked = (
- SystemProperties.getInt("ro.product.first_api_level", 0) >= 29);
+ boolean requireLocked = firstApiLevel >= 29;
checkRootOfTrust(attestation, requireLocked);
break;
case KM_SECURITY_LEVEL_SOFTWARE:
default:
- // TEE attestation has been mandatory since Android 8.0.
- if (SystemProperties.getInt("ro.product.first_api_level", 0) >= 26) {
+ // TEE attestation has been mandatory since Android 8.0 for non-TV devices
+ // and since Android 10.0 for TVs.
+ int apiTeeRequired = isTVDevice() ? 29 : 26;
+ if (firstApiLevel >= apiTeeRequired) {
fail("Unexpected attestation security level: " +
attestation.securityLevelToString(attestationSecurityLevel));
}
@@ -1421,4 +1423,8 @@
}
}
}
+
+ private boolean isTVDevice() {
+ return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 94a7884..b4c930c 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -1357,8 +1357,13 @@
Arrays.equals(loadByteArrayFromString(INVALID_HDR_STATIC_INFO),
staticInfo.array()));
}
- assertFalse("Buffer should not have dynamic HDR metadata present",
- bufferFormat.containsKey(MediaFormat.KEY_HDR10_PLUS_INFO));
+ ByteBuffer hdr10PlusInfo = bufferFormat.getByteBuffer(
+ MediaFormat.KEY_HDR10_PLUS_INFO, null);
+ if (hdr10PlusInfo != null) {
+ assertEquals(
+ "Buffer should not have a valid dynamic HDR metadata present",
+ 0, hdr10PlusInfo.remaining());
+ }
if (!dynamic) {
codec.releaseOutputBuffer(index, true);
diff --git a/tests/tests/media/src/android/media/cts/SystemMediaRouter2Test.java b/tests/tests/media/src/android/media/cts/SystemMediaRouter2Test.java
index 23e2494..c339917 100644
--- a/tests/tests/media/src/android/media/cts/SystemMediaRouter2Test.java
+++ b/tests/tests/media/src/android/media/cts/SystemMediaRouter2Test.java
@@ -334,7 +334,7 @@
@Test
public void testRouteCallbackOnRoutesChanged_whenLocalVolumeChanged() throws Exception {
- if (mAudioManager.isVolumeFixed()) {
+ if (mAudioManager.isVolumeFixed() || mAudioManager.isFullVolumeDevice()) {
return;
}
diff --git a/tests/tests/neuralnetworks/Android.mk b/tests/tests/neuralnetworks/Android.mk
index 7ac51ea..d8b6ee3 100644
--- a/tests/tests/neuralnetworks/Android.mk
+++ b/tests/tests/neuralnetworks/Android.mk
@@ -43,4 +43,3 @@
include $(BUILD_CTS_EXECUTABLE)
include $(nnapi_cts_dir)/benchmark/Android.mk
-include $(nnapi_cts_dir)/tflite_delegate/Android.mk
diff --git a/tests/tests/neuralnetworks/tflite_delegate/Android.bp b/tests/tests/neuralnetworks/tflite_delegate/Android.bp
new file mode 100644
index 0000000..222ec06
--- /dev/null
+++ b/tests/tests/neuralnetworks/tflite_delegate/Android.bp
@@ -0,0 +1,58 @@
+// Copyright (C) 2019 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 {
+ // See: http://go/android-license-faq
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// The "CtsTfliteNnapiDelegateTests_static" has been moved to
+// external/tensorflow/Android.bp, due to the fact that the srcs files
+// are not in the current directory.
+
+// Build the actual CTS module with the static lib above.
+// This is necessary for the build system to pickup the AndroidTest.xml.
+
+cc_test {
+ name: "CtsTfliteNnapiDelegateTestCases",
+ compile_multilib: "both",
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+ whole_static_libs: ["TfliteNnapiDelegateTests_static"],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ "libneuralnetworks",
+ ],
+ static_libs: [
+ "libgtest_ndk_c++",
+ "libgmock_ndk",
+ "libtflite_static",
+ ],
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "mts",
+ "mts-neuralnetworks",
+ "general-tests",
+ ],
+ sdk_version: "current",
+ stl: "c++_static",
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java b/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java
index 0b77a96..8459c5c 100644
--- a/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsRoleManagerAdapter.java
@@ -17,7 +17,6 @@
package android.telecom.cts;
import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
-import static android.telecom.cts.TestUtils.executeShellCommand;
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
@@ -30,11 +29,9 @@
import android.content.Context;
import android.os.Process;
import android.os.UserHandle;
-import android.telecom.TelecomManager;
import android.util.Log;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
@@ -70,6 +67,14 @@
}
}
+ public void removeDialerRoleHolder(String packageName) throws Exception {
+ if (mRoleManager != null) {
+ removeRoleHolder(RoleManager.ROLE_DIALER, packageName);
+ } else {
+ fail("Expected role manager");
+ }
+ }
+
public List<String> getRoleHolder(String roleName) {
List<String> holders = new ArrayList<>();
runWithShellPermissionIdentity(() -> {
diff --git a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyInCallServiceTest.java
index 2fd4626..4cf900f 100644
--- a/tests/tests/telecom/src/android/telecom/cts/ThirdPartyInCallServiceTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/ThirdPartyInCallServiceTest.java
@@ -19,22 +19,17 @@
import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
import android.Manifest;
-import android.app.UiModeManager;
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
-import android.os.RemoteException;
-import android.telecom.TelecomManager;
import android.telecom.cts.thirdptydialer.CtsThirdPtyDialerInCallServiceControl;
-import android.telecom.cts.thirdptyincallservice.CtsThirdPartyInCallService;
import android.telecom.cts.thirdptyincallservice.CtsThirdPartyInCallServiceControl;
import android.telecom.cts.thirdptyincallservice.ICtsThirdPartyInCallServiceControl;
import android.util.Log;
-import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -71,7 +66,11 @@
public void tearDown() throws Exception {
if (mIsDialerRoleAvailable) {
mICtsThirdPartyInCallServiceControl.resetCalls();
- mCtsRoleManagerAdapter.setDialerRoleHolder(mPreviousRoleHolder);
+ if (mPreviousRoleHolder == null) {
+ mCtsRoleManagerAdapter.removeDialerRoleHolder(mThirdPartyPackageName);
+ } else {
+ mCtsRoleManagerAdapter.setDialerRoleHolder(mPreviousRoleHolder);
+ }
}
super.tearDown();
}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java
index fa64856..161e8f2 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java
@@ -146,4 +146,19 @@
"45006", // LGT
"45008" // KT
);
+
+
+ public static final List<String> SUPPORT_TEL_URI_PUBLISH =
+ Arrays.asList(
+ "310410", // AT&T Mobility
+ "310280", // AT&T Mobility
+ "310030", // AT&T Mobility
+ "310070", // AT&T Mobility
+ "310170", // AT&T Mobility
+ "310380", // AT&T Mobility
+ "310560", // AT&T Mobility
+ "310680", // AT&T Mobility
+ "310950", // AT&T Mobility
+ "311180" // AT&T Mobility
+ );
}
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
index 4970d89..a09180f 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
@@ -42,6 +42,7 @@
import android.telephony.TelephonyManager;
import android.telephony.cts.AsyncSmsMessageListener;
import android.telephony.cts.SmsReceiverHelper;
+import android.telephony.cts.CarrierCapability;
import android.telephony.ims.ImsException;
import android.telephony.ims.ImsManager;
import android.telephony.ims.ImsMmTelManager;
@@ -89,6 +90,8 @@
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
+import android.util.Log;
+
/**
* CTS tests for ImsService API.
*/
@@ -1405,6 +1408,12 @@
fail("Cannot find IMS service");
}
+ TelephonyManager tm = (TelephonyManager) getContext()
+ .getSystemService(Context.TELEPHONY_SERVICE);
+
+ String mccmnc = tm.getSimOperator();
+ boolean mTelUriSupported = CarrierCapability.SUPPORT_TEL_URI_PUBLISH.contains(mccmnc);
+
ImsRcsManager imsRcsManager = imsManager.getImsRcsManager(sTestSub);
RcsUceAdapter uceAdapter = imsRcsManager.getUceAdapter();
@@ -1424,7 +1433,13 @@
receivedPidfXml.add(pidfXml);
});
- final Uri imsUri = Uri.fromParts(PhoneAccount.SCHEME_SIP, "test", null);
+ Uri imsUri;
+ if (mTelUriSupported) {
+ imsUri = Uri.fromParts(PhoneAccount.SCHEME_TEL, "0001112222", null);
+ } else {
+ imsUri = Uri.fromParts(PhoneAccount.SCHEME_SIP, "test", null);
+ }
+
StringBuilder expectedUriBuilder = new StringBuilder();
expectedUriBuilder.append("<contact>").append(imsUri.toString()).append("</contact>");
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
index 99d1d33..341d346 100755
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
@@ -39,6 +39,7 @@
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
+import android.text.TextUtils;
import android.view.FrameStats;
import android.view.KeyEvent;
import android.view.WindowAnimationFrameStats;
@@ -189,7 +190,7 @@
getInstrumentation().waitForIdleSync();
// Find the application window.
- final int windowId = findAppWindowId(uiAutomation.getWindows());
+ final int windowId = findAppWindowId(uiAutomation.getWindows(), activity);
assertTrue(windowId >= 0);
// Clear stats to be with a clean slate.
@@ -251,7 +252,7 @@
getInstrumentation().waitForIdleSync();
// Find the application window.
- final int windowId = findAppWindowId(uiAutomation.getWindows());
+ final int windowId = findAppWindowId(uiAutomation.getWindows(), activity);
assertTrue(windowId >= 0);
// Clear stats to be with a clean slate.
@@ -755,11 +756,13 @@
waitForAccessibilityServiceToStart();
}
- private int findAppWindowId(List<AccessibilityWindowInfo> windows) {
+ private int findAppWindowId(List<AccessibilityWindowInfo> windows, Activity activity) {
+ final CharSequence activityTitle = getActivityTitle(getInstrumentation(), activity);
final int windowCount = windows.size();
for (int i = 0; i < windowCount; i++) {
AccessibilityWindowInfo window = windows.get(i);
- if (window.getType() == AccessibilityWindowInfo.TYPE_APPLICATION) {
+ if (window.getType() == AccessibilityWindowInfo.TYPE_APPLICATION
+ && TextUtils.equals(window.getTitle(), activityTitle)) {
return window.getId();
}
}
@@ -769,4 +772,11 @@
private Instrumentation getInstrumentation() {
return InstrumentationRegistry.getInstrumentation();
}
+
+ private static CharSequence getActivityTitle(
+ Instrumentation instrumentation, Activity activity) {
+ final StringBuilder titleBuilder = new StringBuilder();
+ instrumentation.runOnMainSync(() -> titleBuilder.append(activity.getTitle()));
+ return titleBuilder;
+ }
}
diff --git a/tests/tests/view/src/android/view/cts/TooltipTest.java b/tests/tests/view/src/android/view/cts/TooltipTest.java
index 67f27c4..4ce5eba 100644
--- a/tests/tests/view/src/android/view/cts/TooltipTest.java
+++ b/tests/tests/view/src/android/view/cts/TooltipTest.java
@@ -835,15 +835,18 @@
waitOut(halfTimeout);
assertFalse(hasTooltip(mTooltipView));
+ injectShortClick(mTooltipView);
injectHoverMove(source, mTooltipView, 0, 0);
waitOut(halfTimeout);
assertFalse(hasTooltip(mTooltipView));
+ injectShortClick(mTooltipView);
injectHoverMove(source, mTooltipView, 0, jitterHigh);
waitOut(halfTimeout);
assertFalse(hasTooltip(mTooltipView));
// Jitter below threshold should be ignored and the tooltip should be shown.
+ injectShortClick(mTooltipView);
injectHoverMove(source, mTooltipView, 0, 0);
waitOut(halfTimeout);
assertFalse(hasTooltip(mTooltipView));
@@ -857,6 +860,7 @@
injectShortClick(mTooltipView);
assertFalse(hasTooltip(mTooltipView));
+ injectShortClick(mTooltipView);
injectHoverMove(source, mTooltipView, 0, 0);
waitOut(halfTimeout);
assertFalse(hasTooltip(mTooltipView));
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 279c92f..aa99f68 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -248,8 +248,10 @@
<option name="compatibility:exclude-filter" value="CtsPermission3TestCases android.permission3.cts.PermissionTest23#testNoResidualPermissionsOnUninstall" />
<!-- b/198992105 -->
- <option name="compatibility:exclude-filter" value="CtsStatsdAtomHostTestCases android.cts.statsd.atom.UidAtomTests#testDangerousPermissionState" />
- <option name="compatibility:exclude-filter" value="CtsStatsdAtomHostTestCases android.cts.statsd.atom.UidAtomTests#testDangerousPermissionStateSampled" />
+ <option name="compatibility:exclude-filter" value="CtsStatsdAtomHostTestCases android.cts.statsdatom.permissionstate.DangerousPermissionStateTests#testDangerousPermissionState" />
+ <option name="compatibility:exclude-filter" value="CtsStatsdAtomHostTestCases[instant] android.cts.statsdatom.permissionstate.DangerousPermissionStateTests#testDangerousPermissionState" />
+ <option name="compatibility:exclude-filter" value="CtsStatsdAtomHostTestCases android.cts.statsdatom.permissionstate.DangerousPermissionStateTests#testDangerousPermissionStateSampled" />
+ <option name="compatibility:exclude-filter" value="CtsStatsdAtomHostTestCases[instant] android.cts.statsdatom.permissionstate.DangerousPermissionStateTests#testDangerousPermissionStateSampled" />
<!-- b/198682652 -->
<option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.cts.TelephonyCallbackTest#testOnLinkCapacityEstimateChangedByRegisterPhoneStateListener" />
@@ -273,4 +275,6 @@
<option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.ims.cts.RcsUceAdapterTest#testForbidCapabilitiesRequest" />
<option name="compatibility:exclude-filter" value="CtsTelephonyTestCases android.telephony.ims.cts.RcsUceAdapterTest#testTimeoutToRequestCapabilitiesWithPresenceMechanism" />
+ <!-- b/182630972, b/214019488 -->
+ <option name="compatibility:exclude-filter" value="CtsWindowManagerDeviceTestCases android.server.wm.PinnedStackTests#testEnterPipWithMinimalSize" />
</configuration>
diff --git a/tools/cts-tradefed/res/config/cts-system-checkers.xml b/tools/cts-tradefed/res/config/cts-system-checkers.xml
index 7639bf9..e15907e 100644
--- a/tools/cts-tradefed/res/config/cts-system-checkers.xml
+++ b/tools/cts-tradefed/res/config/cts-system-checkers.xml
@@ -27,4 +27,7 @@
<system_checker class="com.android.tradefed.suite.checker.DeviceSettingChecker" />
<system_checker class="com.android.tradefed.suite.checker.SystemServerStatusChecker" />
<system_checker class="com.android.tradefed.suite.checker.SystemServerFileDescriptorChecker" />
+ <system_checker class="com.android.tradefed.suite.checker.DeviceBaselineChecker">
+ <option name="enable-device-baseline-settings" value="false" />
+ </system_checker>
</configuration>