summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt37
-rw-r--r--tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt7
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt15
-rw-r--r--tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt11
-rw-r--r--tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt6
-rw-r--r--tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterFlags.kt21
-rw-r--r--tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestListener.kt65
7 files changed, 95 insertions, 67 deletions
diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt b/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
index 6cd24f800..298d7643c 100644
--- a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
+++ b/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
@@ -1111,11 +1111,11 @@ class SafetyCenterManagerTest {
)
// Because wrong ID, refresh hasn't finished. Wait for timeout.
- listener.receiveSafetyCenterErrorDetails()
+ listener.waitForSafetyCenterRefresh(withErrorEntry = true)
SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_LONG)
SafetySourceReceiver.setResponse(
- Request.Rescan(SINGLE_SOURCE_ID),
+ Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.information)
)
safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
@@ -1185,7 +1185,7 @@ class SafetyCenterManagerTest {
safetyCenterManager.getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)
assertThat(apiSafetySourceData1).isNull()
// Wait for the ongoing refresh to timeout.
- listener.receiveSafetyCenterErrorDetails()
+ listener.waitForSafetyCenterRefresh(withErrorEntry = true)
SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_LONG)
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
@@ -1237,18 +1237,11 @@ class SafetyCenterManagerTest {
REFRESH_REASON_RESCAN_BUTTON_CLICK
)
- val safetyCenterErrorDetailsFromListener = listener.receiveSafetyCenterErrorDetails()
- assertThat(safetyCenterErrorDetailsFromListener)
- .isEqualTo(
- SafetyCenterErrorDetails(
- safetyCenterResourcesApk.getStringByName("refresh_timeout")
- )
- )
+ listener.waitForSafetyCenterRefresh(withErrorEntry = true)
}
@Test
fun refreshSafetySources_withUntrackedSourceThatTimesOut_doesNotTimeOut() {
- SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_SHORT)
SafetyCenterFlags.untrackedSources = setOf(SOURCE_ID_1)
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
// SOURCE_ID_1 will timeout
@@ -1264,14 +1257,11 @@ class SafetyCenterManagerTest {
REFRESH_REASON_RESCAN_BUTTON_CLICK
)
- assertFailsWith(TimeoutCancellationException::class) {
- listener.receiveSafetyCenterErrorDetails(TIMEOUT_SHORT)
- }
+ listener.waitForSafetyCenterRefresh(withErrorEntry = false)
}
@Test
fun refreshSafetySources_withMultipleUntrackedSourcesThatTimeOut_doesNotTimeOut() {
- SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_SHORT)
SafetyCenterFlags.untrackedSources = setOf(SOURCE_ID_1, SOURCE_ID_2)
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
// SOURCE_ID_1 and SOURCE_ID_2 will timeout
@@ -1285,9 +1275,7 @@ class SafetyCenterManagerTest {
REFRESH_REASON_RESCAN_BUTTON_CLICK
)
- assertFailsWith(TimeoutCancellationException::class) {
- listener.receiveSafetyCenterErrorDetails(TIMEOUT_SHORT)
- }
+ listener.waitForSafetyCenterRefresh(withErrorEntry = false)
}
@Test
@@ -1301,25 +1289,20 @@ class SafetyCenterManagerTest {
REFRESH_REASON_RESCAN_BUTTON_CLICK
)
- val safetyCenterErrorDetailsFromListener = listener.receiveSafetyCenterErrorDetails()
- assertThat(safetyCenterErrorDetailsFromListener)
- .isEqualTo(
- SafetyCenterErrorDetails(
- safetyCenterResourcesApk.getStringByName("refresh_timeout")
- )
- )
+ listener.waitForSafetyCenterRefresh(withErrorEntry = true)
}
@Test
fun refreshSafetySources_withTrackedSourceThatHasNoReceiver_doesNotTimeOut() {
- SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_SHORT)
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceOtherPackageConfig)
val listener = safetyCenterTestHelper.addListener()
safetyCenterManager.refreshSafetySourcesWithPermission(REFRESH_REASON_RESCAN_BUTTON_CLICK)
assertFailsWith(TimeoutCancellationException::class) {
- listener.receiveSafetyCenterErrorDetails(TIMEOUT_SHORT)
+ // In this case a refresh isn't even started because there is only a single source
+ // without a receiver.
+ listener.receiveSafetyCenterData(TIMEOUT_SHORT)
}
}
diff --git a/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt b/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt
index de7a18c0e..9534b597a 100644
--- a/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt
+++ b/tests/functional/safetycenter/multiusers/src/android/safetycenter/functional/multiusers/SafetyCenterMultiUsersTest.kt
@@ -35,8 +35,6 @@ import android.safetycenter.SafetyCenterIssue
import android.safetycenter.SafetyCenterManager
import android.safetycenter.SafetyCenterStaticEntry
import android.safetycenter.SafetyCenterStaticEntryGroup
-import android.safetycenter.SafetyCenterStatus.REFRESH_STATUS_DATA_FETCH_IN_PROGRESS
-import android.safetycenter.SafetyCenterStatus.REFRESH_STATUS_NONE
import android.safetycenter.SafetyEvent
import android.safetycenter.SafetySourceData
import androidx.test.core.app.ApplicationProvider
@@ -1279,10 +1277,7 @@ class SafetyCenterMultiUsersTest {
private fun disableQuietModeAndWaitForRefreshToComplete() {
val listener = safetyCenterTestHelper.addListener()
deviceState.workProfile().setQuietMode(false)
- listener.receiveSafetyCenterData {
- it.status.refreshStatus == REFRESH_STATUS_DATA_FETCH_IN_PROGRESS
- }
- listener.receiveSafetyCenterData { it.status.refreshStatus == REFRESH_STATUS_NONE }
+ listener.waitForSafetyCenterRefresh()
}
private fun safetyCenterEntryOkForWork(sourceId: String, managedUserId: Int) =
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt
index 0c952ede2..e2a7802b3 100644
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt
@@ -766,9 +766,8 @@ class SafetyCenterManagerTest {
@get:Rule(order = 2) val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper)
@Test
- fun refreshSafetySources_withShowEntriesOnTimeout_marksSafetySourceAsError() {
+ fun refreshSafetySources_timeout_marksSafetySourceAsError() {
SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_SHORT)
- SafetyCenterFlags.showErrorEntriesOnTimeout = true
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
val listener = safetyCenterTestHelper.addListener()
@@ -786,9 +785,8 @@ class SafetyCenterManagerTest {
}
@Test
- fun refreshSafetySources_withShowEntriesOnTimeout_keepsShowingErrorUntilClearedBySource() {
+ fun refreshSafetySources_timeout_keepsShowingErrorUntilClearedBySource() {
SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_SHORT)
- SafetyCenterFlags.showErrorEntriesOnTimeout = true
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
val listener = safetyCenterTestHelper.addListener()
safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
@@ -816,18 +814,15 @@ class SafetyCenterManagerTest {
}
@Test
- fun refreshSafetySources_withShowEntriesOnTimeout_doesntSetErrorForBackgroundRefreshes() {
+ fun refreshSafetySources_timeout_doesntSetErrorForBackgroundRefreshes() {
SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_SHORT)
- SafetyCenterFlags.showErrorEntriesOnTimeout = true
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
val listener = safetyCenterTestHelper.addListener()
safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(REFRESH_REASON_OTHER)
- val safetyCenterBeforeTimeout = listener.receiveSafetyCenterData()
- assertThat(safetyCenterBeforeTimeout.status.refreshStatus)
- .isEqualTo(REFRESH_STATUS_DATA_FETCH_IN_PROGRESS)
- val safetyCenterDataAfterTimeout = listener.receiveSafetyCenterData()
+ val safetyCenterDataAfterTimeout =
+ listener.waitForSafetyCenterRefresh(withErrorEntry = false)
assertThat(safetyCenterDataAfterTimeout).isEqualTo(safetyCenterDataFromConfig)
}
diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt
index 9e3a33018..d020aac0a 100644
--- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt
+++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt
@@ -18,9 +18,6 @@ package android.safetycenter.hostside.device
import android.content.Context
import android.safetycenter.SafetyCenterManager
-import android.safetycenter.SafetyCenterStatus
-import android.safetycenter.SafetyCenterStatus.REFRESH_STATUS_DATA_FETCH_IN_PROGRESS
-import android.safetycenter.SafetyCenterStatus.REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS
import android.safetycenter.SafetyEvent
import android.safetycenter.SafetySourceErrorDetails
import androidx.test.core.app.ApplicationProvider
@@ -168,12 +165,6 @@ class SafetySourceStateCollectedLoggingHelperTests {
// things are logged.
val listener = safetyCenterTestHelper.addListener()
safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(refreshReason)
- listener.receiveSafetyCenterData {
- it.status.refreshStatus == REFRESH_STATUS_DATA_FETCH_IN_PROGRESS ||
- it.status.refreshStatus == REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS
- }
- listener.receiveSafetyCenterData {
- it.status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_NONE
- }
+ listener.waitForSafetyCenterRefresh()
}
}
diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt
index 6c6336da3..a7009b19e 100644
--- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt
+++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/Coroutines.kt
@@ -30,7 +30,11 @@ import kotlinx.coroutines.withTimeoutOrNull
/** A class that facilitates interacting with coroutines. */
object Coroutines {
- private val TEST_TIMEOUT: Duration
+ /**
+ * The timeout of a test case, typically varies depending on whether the test is running
+ * locally, on pre-submit or post-submit.
+ */
+ val TEST_TIMEOUT: Duration
get() =
Duration.ofMillis(
InstrumentationRegistry.getArguments().getString("timeout_msec", "60000").toLong()
diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterFlags.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterFlags.kt
index 28b621d5c..5cc2e3c8e 100644
--- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterFlags.kt
+++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterFlags.kt
@@ -34,6 +34,7 @@ import android.safetycenter.SafetyCenterManager.REFRESH_REASON_RESCAN_BUTTON_CLI
import android.safetycenter.SafetyCenterManager.REFRESH_REASON_SAFETY_CENTER_ENABLED
import android.safetycenter.SafetySourceData
import com.android.modules.utils.build.SdkLevel
+import com.android.safetycenter.testing.Coroutines.TEST_TIMEOUT
import com.android.safetycenter.testing.Coroutines.TIMEOUT_LONG
import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
import java.time.Duration
@@ -100,13 +101,6 @@ object SafetyCenterFlags {
DurationParser()
)
- /**
- * Flag that determines whether we should show error entries for sources that timeout when
- * refreshing them.
- */
- private val showErrorEntriesOnTimeoutFlag =
- Flag("safety_center_show_error_entries_on_timeout", defaultValue = false, BooleanParser())
-
/** Flag that determines whether we should replace the IconAction of the lock screen source. */
private val replaceLockScreenIconActionFlag =
Flag("safety_center_replace_lock_screen_icon_action", defaultValue = true, BooleanParser())
@@ -115,11 +109,16 @@ object SafetyCenterFlags {
* Flag that determines the time for which a Safety Center refresh is allowed to wait for a
* source to respond to a refresh request before timing out and marking the refresh as finished,
* depending on the refresh reason.
+ *
+ * Unlike the production code, this flag is set to [TEST_TIMEOUT] for all refresh reasons by
+ * default for convenience. UI tests typically will set some data manually rather than going
+ * through a full refresh, and we don't want to timeout the refresh and potentially end up with
+ * error entries in this case (as it could lead to flakyness).
*/
private val refreshSourceTimeoutsFlag =
Flag(
"safety_center_refresh_sources_timeouts_millis",
- defaultValue = getAllRefreshTimeoutsMap(TIMEOUT_LONG),
+ defaultValue = getAllRefreshTimeoutsMap(TEST_TIMEOUT),
MapParser(IntParser(), DurationParser())
)
@@ -302,7 +301,6 @@ object SafetyCenterFlags {
notificationsMinDelayFlag,
immediateNotificationBehaviorIssuesFlag,
notificationResurfaceIntervalFlag,
- showErrorEntriesOnTimeoutFlag,
replaceLockScreenIconActionFlag,
refreshSourceTimeoutsFlag,
resolveActionTimeoutFlag,
@@ -341,14 +339,11 @@ object SafetyCenterFlags {
/** A property that allows getting and setting the [notificationResurfaceIntervalFlag]. */
var notificationResurfaceInterval: Duration by notificationResurfaceIntervalFlag
- /** A property that allows getting and setting the [showErrorEntriesOnTimeoutFlag]. */
- var showErrorEntriesOnTimeout: Boolean by showErrorEntriesOnTimeoutFlag
-
/** A property that allows getting and setting the [replaceLockScreenIconActionFlag]. */
var replaceLockScreenIconAction: Boolean by replaceLockScreenIconActionFlag
/** A property that allows getting and setting the [refreshSourceTimeoutsFlag]. */
- var refreshTimeouts: Map<Int, Duration> by refreshSourceTimeoutsFlag
+ private var refreshTimeouts: Map<Int, Duration> by refreshSourceTimeoutsFlag
/** A property that allows getting and setting the [resolveActionTimeoutFlag]. */
var resolveActionTimeout: Duration by resolveActionTimeoutFlag
diff --git a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestListener.kt b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestListener.kt
index 624c32d5f..8ce5c25d4 100644
--- a/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestListener.kt
+++ b/tests/utils/safetycenter/java/com/android/safetycenter/testing/SafetyCenterTestListener.kt
@@ -18,9 +18,14 @@ package com.android.safetycenter.testing
import android.os.Build.VERSION_CODES.TIRAMISU
import android.safetycenter.SafetyCenterData
+import android.safetycenter.SafetyCenterEntry
import android.safetycenter.SafetyCenterErrorDetails
import android.safetycenter.SafetyCenterManager.OnSafetyCenterDataChangedListener
+import android.safetycenter.SafetyCenterStaticEntry
+import android.safetycenter.SafetyCenterStatus
+import android.text.TextUtils
import androidx.annotation.RequiresApi
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
import com.android.safetycenter.testing.Coroutines.TIMEOUT_LONG
import com.android.safetycenter.testing.Coroutines.runBlockingWithTimeout
import java.time.Duration
@@ -64,6 +69,47 @@ class SafetyCenterTestListener : OnSafetyCenterDataChangedListener {
}
/**
+ * Waits for a full Safety Center refresh to complete, where each change to the underlying
+ * [SafetyCenterData] must happen within the given [timeout].
+ *
+ * @param withErrorEntry optionally check whether we should expect the [SafetyCenterData] to
+ * have or not have at least one an error entry after the refresh completes
+ * @return the [SafetyCenterData] after the refresh completes
+ */
+ fun waitForSafetyCenterRefresh(
+ timeout: Duration = TIMEOUT_LONG,
+ withErrorEntry: Boolean? = null
+ ): SafetyCenterData {
+ receiveSafetyCenterData(timeout) {
+ it.status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_DATA_FETCH_IN_PROGRESS ||
+ it.status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS
+ }
+ val afterRefresh =
+ receiveSafetyCenterData(timeout) {
+ it.status.refreshStatus == SafetyCenterStatus.REFRESH_STATUS_NONE
+ }
+ if (withErrorEntry == null) {
+ return afterRefresh
+ }
+ val errorMessage =
+ SafetyCenterTestData(getApplicationContext())
+ .getRefreshErrorString(numberOfErrorEntries = 1)
+ val containsErrorEntry = afterRefresh.containsAnyEntryWithSummary(errorMessage)
+ if (withErrorEntry && !containsErrorEntry) {
+ throw AssertionError(
+ "No error entry with message: \"$errorMessage\" found in SafetyCenterData" +
+ " after refresh: $afterRefresh"
+ )
+ } else if (!withErrorEntry && containsErrorEntry) {
+ throw AssertionError(
+ "Found an error entry with message: \"$errorMessage\" in SafetyCenterData" +
+ " after refresh: $afterRefresh"
+ )
+ }
+ return afterRefresh
+ }
+
+ /**
* Waits for a [SafetyCenterErrorDetails] update from SafetyCenter within the given [timeout].
*/
fun receiveSafetyCenterErrorDetails(timeout: Duration = TIMEOUT_LONG) =
@@ -74,4 +120,23 @@ class SafetyCenterTestListener : OnSafetyCenterDataChangedListener {
dataChannel.cancel()
errorChannel.cancel()
}
+
+ private companion object {
+ fun SafetyCenterData.containsAnyEntryWithSummary(summary: CharSequence): Boolean =
+ entries().any { TextUtils.equals(it.summary, summary) } ||
+ staticEntries().any { TextUtils.equals(it.summary, summary) }
+
+ fun SafetyCenterData.entries(): List<SafetyCenterEntry> =
+ entriesOrGroups.flatMap {
+ val entry = it.entry
+ if (entry != null) {
+ listOf(entry)
+ } else {
+ it.entryGroup!!.entries
+ }
+ }
+
+ fun SafetyCenterData.staticEntries(): List<SafetyCenterStaticEntry> =
+ staticEntryGroups.flatMap { it.staticEntries }
+ }
}