summaryrefslogtreecommitdiff
path: root/tests/functional/safetycenter/singleuser/src/android/safetycenter
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional/safetycenter/singleuser/src/android/safetycenter')
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt1379
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt300
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterShellCommandsTest.kt95
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetySourceDataFixesTest.kt298
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/NotificationCharacteristics.kt71
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/StatusBarNotificationWithChannel.kt26
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/TestNotificationListener.kt353
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/PrivacySubpageTest.kt222
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterQsActivityTest.kt92
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterStatusCardTest.kt108
-rw-r--r--tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterSubpagesTest.kt1020
11 files changed, 1456 insertions, 2508 deletions
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 b8fd17b37..963c593cd 100644
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterManagerTest.kt
@@ -16,10 +16,9 @@
package android.safetycenter.functional
-import android.app.PendingIntent
+import android.Manifest.permission.MANAGE_SAFETY_CENTER
import android.content.Context
import android.content.Intent
-import android.os.Build
import android.os.Build.VERSION_CODES.TIRAMISU
import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE
import android.os.UserHandle
@@ -63,25 +62,25 @@ import android.safetycenter.config.SafetySource.SAFETY_SOURCE_TYPE_DYNAMIC
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
-import com.android.compatibility.common.preconditions.ScreenLockHelper
import com.android.compatibility.common.util.SystemUtil
import com.android.modules.utils.build.SdkLevel
import com.android.safetycenter.internaldata.SafetyCenterBundles
import com.android.safetycenter.internaldata.SafetyCenterBundles.ISSUES_TO_GROUPS_BUNDLE_KEY
import com.android.safetycenter.internaldata.SafetyCenterEntryId
import com.android.safetycenter.internaldata.SafetyCenterIds
-import com.android.safetycenter.resources.SafetyCenterResourcesContext
+import com.android.safetycenter.resources.SafetyCenterResourcesApk
import com.android.safetycenter.testing.Coroutines.TIMEOUT_LONG
import com.android.safetycenter.testing.Coroutines.TIMEOUT_SHORT
import com.android.safetycenter.testing.Coroutines.waitForWithTimeout
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.dismissSafetyCenterIssueWithPermission
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.getSafetyCenterConfigWithPermission
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.getSafetyCenterDataWithPermission
+import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.getSafetySourceDataWithPermission
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.refreshSafetySourcesWithPermission
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.reportSafetySourceErrorWithPermission
import com.android.safetycenter.testing.SafetyCenterFlags
-import com.android.safetycenter.testing.SafetyCenterFlags.deviceSupportsSafetyCenter
import com.android.safetycenter.testing.SafetyCenterTestConfigs
+import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.ACTION_TEST_ACTIVITY
import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.ACTION_TEST_ACTIVITY_EXPORTED
import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.ANDROID_LOCK_SCREEN_SOURCES_GROUP_ID
import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.DYNAMIC_ALL_OPTIONAL_ID
@@ -116,6 +115,7 @@ import com.android.safetycenter.testing.SafetyCenterTestData.Companion.withAttri
import com.android.safetycenter.testing.SafetyCenterTestData.Companion.withDismissedIssuesIfAtLeastU
import com.android.safetycenter.testing.SafetyCenterTestData.Companion.withoutExtras
import com.android.safetycenter.testing.SafetyCenterTestHelper
+import com.android.safetycenter.testing.SafetyCenterTestRule
import com.android.safetycenter.testing.SafetySourceIntentHandler.Request
import com.android.safetycenter.testing.SafetySourceIntentHandler.Response
import com.android.safetycenter.testing.SafetySourceReceiver
@@ -130,15 +130,14 @@ import com.android.safetycenter.testing.SafetySourceTestData.Companion.INFORMATI
import com.android.safetycenter.testing.SafetySourceTestData.Companion.RECOMMENDATION_ISSUE_ID
import com.android.safetycenter.testing.SettingsPackage.getSettingsPackageName
import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
+import com.android.safetycenter.testing.SupportsSafetyCenterRule
import com.google.common.base.Preconditions.checkState
import com.google.common.truth.Truth.assertThat
import java.time.Duration
import kotlin.test.assertFailsWith
import kotlinx.coroutines.TimeoutCancellationException
-import org.junit.After
import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
-import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -146,588 +145,657 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SafetyCenterManagerTest {
private val context: Context = getApplicationContext()
- private val safetyCenterResourcesContext = SafetyCenterResourcesContext.forTests(context)
+ private val safetyCenterResourcesApk = SafetyCenterResourcesApk.forTests(context)
private val safetyCenterTestHelper = SafetyCenterTestHelper(context)
private val safetySourceTestData = SafetySourceTestData(context)
private val safetyCenterTestData = SafetyCenterTestData(context)
private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
private val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java)!!
- private val safetyCenterStatusOk =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_title"),
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_summary")
- )
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
- .build()
+ private val safetyCenterStatusOk: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_title"),
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_summary")
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
+ .build()
+
+ private val safetyCenterStatusUnknownScanning: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName("scanning_title"),
+ safetyCenterResourcesApk.getStringByName("loading_summary")
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_UNKNOWN)
+ .setRefreshStatus(REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS)
+ .build()
+
+ private val safetyCenterStatusOkOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_title"),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
+ .build()
+
+ private val safetyCenterStatusOkReviewOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_ok_review_title"
+ ),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
+ .build()
+
+ private val safetyCenterStatusOkReview: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_ok_review_title"
+ ),
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_ok_review_summary"
+ )
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
+ .build()
+
+ private val safetyCenterStatusGeneralRecommendationOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_safety_recommendation_title"
+ ),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_RECOMMENDATION)
+ .build()
+
+ private val safetyCenterStatusAccountRecommendationOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_account_recommendation_title"
+ ),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_RECOMMENDATION)
+ .build()
+
+ private val safetyCenterStatusDeviceRecommendationOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_device_recommendation_title"
+ ),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_RECOMMENDATION)
+ .build()
- private val safetyCenterStatusUnknownScanning =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName("scanning_title"),
- safetyCenterResourcesContext.getStringByName("loading_summary")
+ private val safetyCenterStatusGeneralCriticalOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_critical_safety_warning_title"
+ ),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
+ .build()
+
+ private val safetyCenterStatusGeneralCriticalTwoAlerts: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_critical_safety_warning_title"
+ ),
+ safetyCenterTestData.getAlertString(2)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
+ .build()
+
+ private val safetyCenterStatusAccountCriticalOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_critical_account_warning_title"
+ ),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
+ .build()
+
+ private val safetyCenterStatusAccountCriticalTwoAlerts: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_critical_account_warning_title"
+ ),
+ safetyCenterTestData.getAlertString(2)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
+ .build()
+
+ private val safetyCenterStatusDeviceCriticalOneAlert: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_critical_device_warning_title"
+ ),
+ safetyCenterTestData.getAlertString(1)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
+ .build()
+
+ private val safetyCenterStatusDeviceCriticalTwoAlerts: SafetyCenterStatus
+ get() =
+ SafetyCenterStatus.Builder(
+ safetyCenterResourcesApk.getStringByName(
+ "overall_severity_level_critical_device_warning_title"
+ ),
+ safetyCenterTestData.getAlertString(2)
+ )
+ .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
+ .build()
+
+ private val safetyCenterEntryOrGroupRecommendation: SafetyCenterEntryOrGroup
+ get() =
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
+ )
+
+ private val safetyCenterEntryOrGroupCritical: SafetyCenterEntryOrGroup
+ get() =
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryCritical(SINGLE_SOURCE_ID)
+ )
+
+ private val safetyCenterEntryGroupMixedFromComplexConfig: SafetyCenterEntryOrGroup
+ get() =
+ SafetyCenterEntryOrGroup(
+ SafetyCenterEntryGroup.Builder(MIXED_STATEFUL_GROUP_ID, "OK")
+ .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNKNOWN)
+ .setSummary(safetyCenterResourcesApk.getStringByName("group_unknown_summary"))
+ .setEntries(
+ listOf(
+ safetyCenterTestData.safetyCenterEntryDefault(DYNAMIC_IN_STATEFUL_ID),
+ SafetyCenterEntry.Builder(
+ SafetyCenterTestData.entryId(STATIC_IN_STATEFUL_ID),
+ "OK"
+ )
+ .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNSPECIFIED)
+ .setSummary("OK")
+ .setPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent(
+ explicit = false
+ )
+ )
+ .setSeverityUnspecifiedIconType(
+ SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON
+ )
+ .build()
+ )
+ )
+ .setSeverityUnspecifiedIconType(
+ SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION
+ )
+ .build()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_UNKNOWN)
- .setRefreshStatus(REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS)
- .build()
- private val safetyCenterStatusOkOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_title"),
- safetyCenterTestData.getAlertString(1)
+ private val safetyCenterStaticEntryGroupFromComplexConfig: SafetyCenterStaticEntryGroup
+ get() =
+ SafetyCenterStaticEntryGroup(
+ "OK",
+ listOf(
+ SafetyCenterStaticEntry.Builder("OK")
+ .setPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent(
+ explicit = false
+ )
+ )
+ .build(),
+ SafetyCenterStaticEntry.Builder("OK")
+ .setSummary("OK")
+ .setPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent(
+ explicit = false
+ )
+ )
+ .build()
+ )
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
- .build()
- private val safetyCenterStatusOkReviewOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_ok_review_title"
- ),
- safetyCenterTestData.getAlertString(1)
+ private val safetyCenterStaticEntryGroupMixedFromComplexConfig: SafetyCenterStaticEntryGroup
+ get() =
+ SafetyCenterStaticEntryGroup(
+ "OK",
+ listOf(
+ SafetyCenterStaticEntry.Builder("OK")
+ .setSummary("OK")
+ .setPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent()
+ )
+ .build(),
+ SafetyCenterStaticEntry.Builder("OK")
+ .setSummary("OK")
+ .setPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent(
+ explicit = false
+ )
+ )
+ .build()
+ )
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
- .build()
- private val safetyCenterStatusOkReview =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_ok_review_title"
- ),
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_ok_review_summary"
+ private val safetyCenterStaticEntryGroupMixedUpdatedFromComplexConfig:
+ SafetyCenterStaticEntryGroup
+ get() =
+ SafetyCenterStaticEntryGroup(
+ "OK",
+ listOf(
+ SafetyCenterStaticEntry.Builder("Unspecified title")
+ .setSummary("Unspecified summary")
+ .setPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent()
+ )
+ .build(),
+ SafetyCenterStaticEntry.Builder("OK")
+ .setSummary("OK")
+ .setPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent(
+ explicit = false
+ )
+ )
+ .build()
)
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_OK)
- .build()
- private val safetyCenterStatusGeneralRecommendationOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_safety_recommendation_title"
+ private val safetyCenterDataFromConfigScanning: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusUnknownScanning,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryDefault(SINGLE_SOURCE_ID)
+ )
),
- safetyCenterTestData.getAlertString(1)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_RECOMMENDATION)
- .build()
- private val safetyCenterStatusAccountRecommendationOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_account_recommendation_title"
+ private val safetyCenterDataFromConfig: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterTestData.safetyCenterStatusUnknown,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryDefault(SINGLE_SOURCE_ID)
+ )
),
- safetyCenterTestData.getAlertString(1)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_RECOMMENDATION)
- .build()
- private val safetyCenterStatusDeviceRecommendationOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_device_recommendation_title"
+ private val safetyCenterDataUnspecified: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOk,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryUnspecified(SINGLE_SOURCE_ID)
+ )
),
- safetyCenterTestData.getAlertString(1)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_RECOMMENDATION)
- .build()
- private val safetyCenterStatusGeneralCriticalOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_critical_safety_warning_title"
+ private val safetyCenterDataOk: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOk,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryOk(SINGLE_SOURCE_ID)
+ )
),
- safetyCenterTestData.getAlertString(1)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
- .build()
- private val safetyCenterStatusGeneralCriticalTwoAlerts =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_critical_safety_warning_title"
+ private val safetyCenterDataOkWithIconAction: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOk,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData
+ .safetyCenterEntryOkBuilder(SINGLE_SOURCE_ID)
+ .setIconAction(
+ ICON_ACTION_TYPE_INFO,
+ safetySourceTestData.createTestActivityRedirectPendingIntent()
+ )
+ .build()
+ )
),
- safetyCenterTestData.getAlertString(2)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
- .build()
- private val safetyCenterStatusAccountCriticalOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_critical_account_warning_title"
+ private val safetyCenterDataUnknownScanningWithError: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusUnknownScanning,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryError(SINGLE_SOURCE_ID)
+ )
),
- safetyCenterTestData.getAlertString(1)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
- .build()
- private val safetyCenterStatusAccountCriticalTwoAlerts =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_critical_account_warning_title"
+ private val safetyCenterDataUnknownReviewError: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterTestData.safetyCenterStatusUnknown,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryError(SINGLE_SOURCE_ID)
+ )
),
- safetyCenterTestData.getAlertString(2)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
- .build()
- private val safetyCenterStatusDeviceCriticalOneAlert =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_critical_device_warning_title"
+ private val safetyCenterDataOkOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOkOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueInformation(SINGLE_SOURCE_ID)),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryOk(SINGLE_SOURCE_ID)
+ )
),
- safetyCenterTestData.getAlertString(1)
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
- .build()
- private val safetyCenterStatusDeviceCriticalTwoAlerts =
- SafetyCenterStatus.Builder(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_critical_device_warning_title"
- ),
- safetyCenterTestData.getAlertString(2)
+ private val safetyCenterDataOkReviewCriticalEntry: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOkReview,
+ emptyList(),
+ listOf(safetyCenterEntryOrGroupCritical),
+ emptyList()
)
- .setSeverityLevel(OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING)
- .build()
- private val safetyCenterEntryOrGroupRecommendation =
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
- )
+ private val safetyCenterDataOkReviewRecommendationEntry: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOkReview,
+ emptyList(),
+ listOf(safetyCenterEntryOrGroupRecommendation),
+ emptyList()
+ )
- private val safetyCenterEntryOrGroupCritical =
- SafetyCenterEntryOrGroup(safetyCenterTestData.safetyCenterEntryCritical(SINGLE_SOURCE_ID))
+ private val safetyCenterDataOkReviewOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOkReviewOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueInformation(SINGLE_SOURCE_ID)),
+ listOf(safetyCenterEntryOrGroupCritical),
+ emptyList()
+ )
- private val safetyCenterEntryGroupMixedFromComplexConfig =
- SafetyCenterEntryOrGroup(
- SafetyCenterEntryGroup.Builder(MIXED_STATEFUL_GROUP_ID, "OK")
- .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNKNOWN)
- .setSummary(safetyCenterResourcesContext.getStringByName("group_unknown_summary"))
- .setEntries(
- listOf(
- safetyCenterTestData.safetyCenterEntryDefault(DYNAMIC_IN_STATEFUL_ID),
- SafetyCenterEntry.Builder(
- SafetyCenterTestData.entryId(STATIC_IN_STATEFUL_ID),
- "OK"
- )
- .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNSPECIFIED)
- .setSummary("OK")
- .setPendingIntent(
- safetySourceTestData.testActivityRedirectPendingIntent
- )
- .setSeverityUnspecifiedIconType(SEVERITY_UNSPECIFIED_ICON_TYPE_NO_ICON)
- .build()
+ private val safetyCenterDataGeneralRecommendationOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusGeneralRecommendationOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueRecommendation(SINGLE_SOURCE_ID)),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
)
- )
- .setSeverityUnspecifiedIconType(SEVERITY_UNSPECIFIED_ICON_TYPE_NO_RECOMMENDATION)
- .build()
- )
-
- private val safetyCenterStaticEntryGroupFromComplexConfig =
- SafetyCenterStaticEntryGroup(
- "OK",
- listOf(
- SafetyCenterStaticEntry.Builder("OK")
- .setPendingIntent(safetySourceTestData.testActivityRedirectPendingIntent)
- .build(),
- SafetyCenterStaticEntry.Builder("OK")
- .setSummary("OK")
- .setPendingIntent(safetySourceTestData.testActivityRedirectPendingIntent)
- .build()
+ ),
+ emptyList()
)
- )
- private val safetyCenterStaticEntryGroupMixedFromComplexConfig =
- SafetyCenterStaticEntryGroup(
- "OK",
- listOf(
- SafetyCenterStaticEntry.Builder("OK")
- .setSummary("OK")
- .setPendingIntent(safetySourceTestData.testActivityRedirectPendingIntent)
- .build(),
- SafetyCenterStaticEntry.Builder("OK")
- .setSummary("OK")
- .setPendingIntent(safetySourceTestData.testActivityRedirectPendingIntent)
- .build()
+ private val safetyCenterDataGeneralRecommendationAlertWithConfirmation: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusGeneralRecommendationOneAlert,
+ listOf(
+ safetyCenterTestData.safetyCenterIssueRecommendation(
+ SINGLE_SOURCE_ID,
+ confirmationDialog = true
+ )
+ ),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
+ )
+ ),
+ emptyList()
)
- )
- private val safetyCenterStaticEntryGroupMixedUpdatedFromComplexConfig =
- SafetyCenterStaticEntryGroup(
- "OK",
- listOf(
- SafetyCenterStaticEntry.Builder("Unspecified title")
- .setSummary("Unspecified summary")
- .setPendingIntent(safetySourceTestData.testActivityRedirectPendingIntent)
- .build(),
- SafetyCenterStaticEntry.Builder("OK")
- .setSummary("OK")
- .setPendingIntent(safetySourceTestData.testActivityRedirectPendingIntent)
- .build()
+ private val safetyCenterDataAccountRecommendationOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusAccountRecommendationOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueRecommendation(SINGLE_SOURCE_ID)),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
+ )
+ ),
+ emptyList()
)
- )
-
- private val safetyCenterDataFromConfigScanning =
- SafetyCenterData(
- safetyCenterStatusUnknownScanning,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryDefault(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataFromConfig =
- SafetyCenterData(
- safetyCenterTestData.safetyCenterStatusUnknown,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryDefault(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataUnspecified =
- SafetyCenterData(
- safetyCenterStatusOk,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryUnspecified(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataOk =
- SafetyCenterData(
- safetyCenterStatusOk,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(safetyCenterTestData.safetyCenterEntryOk(SINGLE_SOURCE_ID))
- ),
- emptyList()
- )
-
- private val safetyCenterDataOkWithIconAction =
- SafetyCenterData(
- safetyCenterStatusOk,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData
- .safetyCenterEntryOkBuilder(SINGLE_SOURCE_ID)
- .setIconAction(
- ICON_ACTION_TYPE_INFO,
- safetySourceTestData.testActivityRedirectPendingIntent
- )
- .build()
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataUnknownScanningWithError =
- SafetyCenterData(
- safetyCenterStatusUnknownScanning,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryError(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
- private val safetyCenterDataUnknownReviewError =
- SafetyCenterData(
- safetyCenterTestData.safetyCenterStatusUnknown,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryError(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataOkOneAlert =
- SafetyCenterData(
- safetyCenterStatusOkOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueInformation(SINGLE_SOURCE_ID)),
- listOf(
- SafetyCenterEntryOrGroup(safetyCenterTestData.safetyCenterEntryOk(SINGLE_SOURCE_ID))
- ),
- emptyList()
- )
-
- private val safetyCenterDataOkReviewCriticalEntry =
- SafetyCenterData(
- safetyCenterStatusOkReview,
- emptyList(),
- listOf(safetyCenterEntryOrGroupCritical),
- emptyList()
- )
-
- private val safetyCenterDataOkReviewRecommendationEntry =
- SafetyCenterData(
- safetyCenterStatusOkReview,
- emptyList(),
- listOf(safetyCenterEntryOrGroupRecommendation),
- emptyList()
- )
-
- private val safetyCenterDataOkReviewOneAlert =
- SafetyCenterData(
- safetyCenterStatusOkReviewOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueInformation(SINGLE_SOURCE_ID)),
- listOf(safetyCenterEntryOrGroupCritical),
- emptyList()
- )
-
- private val safetyCenterDataGeneralRecommendationOneAlert =
- SafetyCenterData(
- safetyCenterStatusGeneralRecommendationOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueRecommendation(SINGLE_SOURCE_ID)),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataGeneralRecommendationAlertWithConfirmation =
- SafetyCenterData(
- safetyCenterStatusGeneralRecommendationOneAlert,
- listOf(
- safetyCenterTestData.safetyCenterIssueRecommendation(
- SINGLE_SOURCE_ID,
- confirmationDialog = true
- )
- ),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataAccountRecommendationOneAlert =
- SafetyCenterData(
- safetyCenterStatusAccountRecommendationOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueRecommendation(SINGLE_SOURCE_ID)),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataDeviceRecommendationOneAlert =
- SafetyCenterData(
- safetyCenterStatusDeviceRecommendationOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueRecommendation(SINGLE_SOURCE_ID)),
- listOf(
- SafetyCenterEntryOrGroup(
- safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
- )
- ),
- emptyList()
- )
-
- private val safetyCenterDataGeneralCriticalOneAlert =
- SafetyCenterData(
- safetyCenterStatusGeneralCriticalOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueCritical(SINGLE_SOURCE_ID)),
- listOf(safetyCenterEntryOrGroupCritical),
- emptyList()
- )
-
- private val safetyCenterDataAccountCriticalOneAlert =
- SafetyCenterData(
- safetyCenterStatusAccountCriticalOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueCritical(SINGLE_SOURCE_ID)),
- listOf(safetyCenterEntryOrGroupCritical),
- emptyList()
- )
+ private val safetyCenterDataDeviceRecommendationOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusDeviceRecommendationOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueRecommendation(SINGLE_SOURCE_ID)),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ safetyCenterTestData.safetyCenterEntryRecommendation(SINGLE_SOURCE_ID)
+ )
+ ),
+ emptyList()
+ )
- private val safetyCenterDataDeviceCriticalOneAlert =
- SafetyCenterData(
- safetyCenterStatusDeviceCriticalOneAlert,
- listOf(safetyCenterTestData.safetyCenterIssueCritical(SINGLE_SOURCE_ID)),
- listOf(safetyCenterEntryOrGroupCritical),
- emptyList()
- )
+ private val safetyCenterDataGeneralCriticalOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusGeneralCriticalOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueCritical(SINGLE_SOURCE_ID)),
+ listOf(safetyCenterEntryOrGroupCritical),
+ emptyList()
+ )
- private val safetyCenterDataCriticalOneAlertInFlight =
- SafetyCenterData(
- safetyCenterStatusGeneralCriticalOneAlert,
- listOf(
- safetyCenterTestData.safetyCenterIssueCritical(
- SINGLE_SOURCE_ID,
- isActionInFlight = true
- )
- ),
- listOf(safetyCenterEntryOrGroupCritical),
- emptyList()
- )
+ private val safetyCenterDataAccountCriticalOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusAccountCriticalOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueCritical(SINGLE_SOURCE_ID)),
+ listOf(safetyCenterEntryOrGroupCritical),
+ emptyList()
+ )
- private val safetyCenterDataOkReviewOneDismissedAlertInFlight =
- SafetyCenterData(
- safetyCenterStatusOkReview,
- emptyList(),
+ private val safetyCenterDataDeviceCriticalOneAlert: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusDeviceCriticalOneAlert,
+ listOf(safetyCenterTestData.safetyCenterIssueCritical(SINGLE_SOURCE_ID)),
listOf(safetyCenterEntryOrGroupCritical),
emptyList()
)
- .withDismissedIssuesIfAtLeastU(
+
+ private val safetyCenterDataCriticalOneAlertInFlight: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusGeneralCriticalOneAlert,
listOf(
safetyCenterTestData.safetyCenterIssueCritical(
SINGLE_SOURCE_ID,
isActionInFlight = true
)
- )
+ ),
+ listOf(safetyCenterEntryOrGroupCritical),
+ emptyList()
)
- private val safetyCenterDataFromComplexConfig =
- SafetyCenterData(
- safetyCenterTestData.safetyCenterStatusUnknown,
- emptyList(),
- listOf(
- SafetyCenterEntryOrGroup(
- SafetyCenterEntryGroup.Builder(DYNAMIC_GROUP_ID, "OK")
- .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNKNOWN)
- .setSummary(
- safetyCenterResourcesContext.getStringByName("group_unknown_summary")
+ private val safetyCenterDataOkReviewOneDismissedAlertInFlight: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterStatusOkReview,
+ emptyList(),
+ listOf(safetyCenterEntryOrGroupCritical),
+ emptyList()
+ )
+ .withDismissedIssuesIfAtLeastU(
+ listOf(
+ safetyCenterTestData.safetyCenterIssueCritical(
+ SINGLE_SOURCE_ID,
+ isActionInFlight = true
)
- .setSeverityUnspecifiedIconType(SEVERITY_UNSPECIFIED_ICON_TYPE_PRIVACY)
- .setEntries(
- listOf(
- safetyCenterTestData.safetyCenterEntryDefault(DYNAMIC_BAREBONE_ID),
- safetyCenterTestData
- .safetyCenterEntryDefaultBuilder(DYNAMIC_ALL_OPTIONAL_ID)
- .setEnabled(false)
- .build(),
- safetyCenterTestData
- .safetyCenterEntryDefaultBuilder(DYNAMIC_DISABLED_ID)
- .setPendingIntent(null)
- .setEnabled(false)
- .build(),
- safetyCenterTestData
- .safetyCenterEntryDefaultBuilder(DYNAMIC_OTHER_PACKAGE_ID)
- .setPendingIntent(null)
- .setEnabled(false)
- .build()
+ )
+ )
+
+ private val safetyCenterDataFromComplexConfig: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterTestData.safetyCenterStatusUnknown,
+ emptyList(),
+ listOf(
+ SafetyCenterEntryOrGroup(
+ SafetyCenterEntryGroup.Builder(DYNAMIC_GROUP_ID, "OK")
+ .setSeverityLevel(ENTRY_SEVERITY_LEVEL_UNKNOWN)
+ .setSummary(
+ safetyCenterResourcesApk.getStringByName("group_unknown_summary")
)
- )
- .build()
+ .setSeverityUnspecifiedIconType(SEVERITY_UNSPECIFIED_ICON_TYPE_PRIVACY)
+ .setEntries(
+ listOf(
+ safetyCenterTestData.safetyCenterEntryDefault(
+ DYNAMIC_BAREBONE_ID
+ ),
+ safetyCenterTestData
+ .safetyCenterEntryDefaultBuilder(DYNAMIC_ALL_OPTIONAL_ID)
+ .setEnabled(false)
+ .build(),
+ safetyCenterTestData
+ .safetyCenterEntryDefaultBuilder(DYNAMIC_DISABLED_ID)
+ .setPendingIntent(null)
+ .setEnabled(false)
+ .build(),
+ safetyCenterTestData
+ .safetyCenterEntryDefaultBuilder(DYNAMIC_OTHER_PACKAGE_ID)
+ .setPendingIntent(null)
+ .setEnabled(false)
+ .build()
+ )
+ )
+ .build()
+ ),
+ safetyCenterEntryGroupMixedFromComplexConfig
),
- safetyCenterEntryGroupMixedFromComplexConfig
- ),
- listOf(
- safetyCenterStaticEntryGroupFromComplexConfig,
- safetyCenterStaticEntryGroupMixedFromComplexConfig
+ listOf(
+ safetyCenterStaticEntryGroupFromComplexConfig,
+ safetyCenterStaticEntryGroupMixedFromComplexConfig
+ )
)
- )
- private val safetyCenterDataFromComplexConfigUpdated =
- SafetyCenterData(
- safetyCenterTestData.safetyCenterStatusCritical(6),
- listOf(
- safetyCenterTestData.safetyCenterIssueCritical(
- DYNAMIC_BAREBONE_ID,
- groupId = DYNAMIC_GROUP_ID
- ),
- safetyCenterTestData.safetyCenterIssueCritical(
- ISSUE_ONLY_BAREBONE_ID,
- groupId = ISSUE_ONLY_GROUP_ID
- ),
- safetyCenterTestData.safetyCenterIssueRecommendation(
- DYNAMIC_DISABLED_ID,
- groupId = DYNAMIC_GROUP_ID
- ),
- safetyCenterTestData.safetyCenterIssueRecommendation(
- ISSUE_ONLY_ALL_OPTIONAL_ID,
- groupId = ISSUE_ONLY_GROUP_ID
- ),
- safetyCenterTestData.safetyCenterIssueInformation(
- DYNAMIC_IN_STATELESS_ID,
- groupId = MIXED_STATELESS_GROUP_ID
+ private val safetyCenterDataFromComplexConfigUpdated: SafetyCenterData
+ get() =
+ SafetyCenterData(
+ safetyCenterTestData.safetyCenterStatusCritical(6),
+ listOf(
+ safetyCenterTestData.safetyCenterIssueCritical(
+ DYNAMIC_BAREBONE_ID,
+ groupId = DYNAMIC_GROUP_ID
+ ),
+ safetyCenterTestData.safetyCenterIssueCritical(
+ ISSUE_ONLY_BAREBONE_ID,
+ groupId = ISSUE_ONLY_GROUP_ID
+ ),
+ safetyCenterTestData.safetyCenterIssueRecommendation(
+ DYNAMIC_DISABLED_ID,
+ groupId = DYNAMIC_GROUP_ID
+ ),
+ safetyCenterTestData.safetyCenterIssueRecommendation(
+ ISSUE_ONLY_ALL_OPTIONAL_ID,
+ groupId = ISSUE_ONLY_GROUP_ID
+ ),
+ safetyCenterTestData.safetyCenterIssueInformation(
+ DYNAMIC_IN_STATELESS_ID,
+ groupId = MIXED_STATELESS_GROUP_ID
+ ),
+ safetyCenterTestData.safetyCenterIssueInformation(
+ ISSUE_ONLY_IN_STATELESS_ID,
+ groupId = MIXED_STATELESS_GROUP_ID
+ )
),
- safetyCenterTestData.safetyCenterIssueInformation(
- ISSUE_ONLY_IN_STATELESS_ID,
- groupId = MIXED_STATELESS_GROUP_ID
- )
- ),
- listOf(
- SafetyCenterEntryOrGroup(
- SafetyCenterEntryGroup.Builder(DYNAMIC_GROUP_ID, "OK")
- .setSeverityLevel(ENTRY_SEVERITY_LEVEL_CRITICAL_WARNING)
- .setSeverityUnspecifiedIconType(SEVERITY_UNSPECIFIED_ICON_TYPE_PRIVACY)
- .setSummary("Critical summary")
- .setEntries(
- listOf(
- safetyCenterTestData.safetyCenterEntryCritical(DYNAMIC_BAREBONE_ID),
- safetyCenterTestData
- .safetyCenterEntryDefaultBuilder(DYNAMIC_ALL_OPTIONAL_ID)
- .setEnabled(false)
- .build(),
- safetyCenterTestData.safetyCenterEntryRecommendation(
- DYNAMIC_DISABLED_ID
- ),
- safetyCenterTestData.safetyCenterEntryUnspecified(
- DYNAMIC_HIDDEN_ID,
- pendingIntent = null
- ),
- safetyCenterTestData.safetyCenterEntryOk(
- DYNAMIC_HIDDEN_WITH_SEARCH_ID
- ),
- safetyCenterTestData
- .safetyCenterEntryDefaultBuilder(DYNAMIC_OTHER_PACKAGE_ID)
- .setPendingIntent(null)
- .setEnabled(false)
- .build()
+ listOf(
+ SafetyCenterEntryOrGroup(
+ SafetyCenterEntryGroup.Builder(DYNAMIC_GROUP_ID, "OK")
+ .setSeverityLevel(ENTRY_SEVERITY_LEVEL_CRITICAL_WARNING)
+ .setSeverityUnspecifiedIconType(SEVERITY_UNSPECIFIED_ICON_TYPE_PRIVACY)
+ .setSummary("Critical summary")
+ .setEntries(
+ listOf(
+ safetyCenterTestData.safetyCenterEntryCritical(
+ DYNAMIC_BAREBONE_ID
+ ),
+ safetyCenterTestData
+ .safetyCenterEntryDefaultBuilder(DYNAMIC_ALL_OPTIONAL_ID)
+ .setEnabled(false)
+ .build(),
+ safetyCenterTestData.safetyCenterEntryRecommendation(
+ DYNAMIC_DISABLED_ID
+ ),
+ safetyCenterTestData.safetyCenterEntryUnspecified(
+ DYNAMIC_HIDDEN_ID,
+ pendingIntent = null
+ ),
+ safetyCenterTestData.safetyCenterEntryOk(
+ DYNAMIC_HIDDEN_WITH_SEARCH_ID
+ ),
+ safetyCenterTestData
+ .safetyCenterEntryDefaultBuilder(DYNAMIC_OTHER_PACKAGE_ID)
+ .setPendingIntent(null)
+ .setEnabled(false)
+ .build()
+ )
)
- )
- .build()
+ .build()
+ ),
+ safetyCenterEntryGroupMixedFromComplexConfig
),
- safetyCenterEntryGroupMixedFromComplexConfig
- ),
- listOf(
- safetyCenterStaticEntryGroupFromComplexConfig,
- safetyCenterStaticEntryGroupMixedUpdatedFromComplexConfig
+ listOf(
+ safetyCenterStaticEntryGroupFromComplexConfig,
+ safetyCenterStaticEntryGroupMixedUpdatedFromComplexConfig
+ )
)
- )
- // JUnit's Assume is not supported in @BeforeClass by the CTS tests runner, so this is used to
- // manually skip the setup and teardown methods.
- private val shouldRunTests = context.deviceSupportsSafetyCenter()
+ @get:Rule(order = 1) val supportsSafetyCenterRule = SupportsSafetyCenterRule(context)
+ @get:Rule(order = 2) val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper)
- @Before
- fun assumeDeviceSupportsSafetyCenterToRunTests() {
- assumeTrue(shouldRunTests)
- }
+ @Test
+ fun getSafetySourceData_differentPackageWithManageSafetyCenterPermission_returnsData() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexConfig)
- @Before
- fun enableSafetyCenterBeforeTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.setup()
- }
+ val data =
+ callWithShellPermissionIdentity(MANAGE_SAFETY_CENTER) {
+ safetyCenterManager.getSafetySourceData(DYNAMIC_OTHER_PACKAGE_ID)
+ }
- @After
- fun clearDataAfterTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.reset()
+ assertThat(data).isNull()
}
@Test
@@ -808,9 +876,9 @@ class SafetyCenterManagerTest {
val status1 = listener.receiveSafetyCenterData().status
assertThat(status1.refreshStatus).isEqualTo(REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS)
assertThat(status1.title.toString())
- .isEqualTo(safetyCenterResourcesContext.getStringByName("scanning_title"))
+ .isEqualTo(safetyCenterResourcesApk.getStringByName("scanning_title"))
assertThat(status1.summary.toString())
- .isEqualTo(safetyCenterResourcesContext.getStringByName("loading_summary"))
+ .isEqualTo(safetyCenterResourcesApk.getStringByName("loading_summary"))
val status2 = listener.receiveSafetyCenterData().status
assertThat(status2.refreshStatus).isEqualTo(REFRESH_STATUS_NONE)
assertThat(status2).isEqualTo(safetyCenterStatusOk)
@@ -832,9 +900,9 @@ class SafetyCenterManagerTest {
val status1 = listener.receiveSafetyCenterData().status
assertThat(status1.refreshStatus).isEqualTo(REFRESH_STATUS_DATA_FETCH_IN_PROGRESS)
assertThat(status1.title.toString())
- .isEqualTo(safetyCenterResourcesContext.getStringByName("scanning_title"))
+ .isEqualTo(safetyCenterResourcesApk.getStringByName("scanning_title"))
assertThat(status1.summary.toString())
- .isEqualTo(safetyCenterResourcesContext.getStringByName("loading_summary"))
+ .isEqualTo(safetyCenterResourcesApk.getStringByName("loading_summary"))
val status2 = listener.receiveSafetyCenterData().status
assertThat(status2.refreshStatus).isEqualTo(REFRESH_STATUS_NONE)
assertThat(status2).isEqualTo(safetyCenterStatusOk)
@@ -858,13 +926,78 @@ class SafetyCenterManagerTest {
assertThat(status1.refreshStatus).isEqualTo(REFRESH_STATUS_DATA_FETCH_IN_PROGRESS)
assertThat(status1.title.toString()).isEqualTo(safetyCenterStatusOk.title.toString())
assertThat(status1.summary.toString())
- .isEqualTo(safetyCenterResourcesContext.getStringByName("loading_summary"))
+ .isEqualTo(safetyCenterResourcesApk.getStringByName("loading_summary"))
val status2 = listener.receiveSafetyCenterData().status
assertThat(status2.refreshStatus).isEqualTo(REFRESH_STATUS_NONE)
assertThat(status2).isEqualTo(safetyCenterStatusOk)
}
@Test
+ fun refreshSafetySources_reasonPageOpen_allowedByFlag_broadcastSent() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.noPageOpenConfig)
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.information)
+ SafetyCenterFlags.overrideRefreshOnPageOpenSources = setOf(SINGLE_SOURCE_ID)
+ SafetySourceReceiver.setResponse(
+ Request.Refresh(SINGLE_SOURCE_ID),
+ Response.SetData(safetySourceTestData.informationWithIssue)
+ )
+
+ safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
+ REFRESH_REASON_PAGE_OPEN
+ )
+
+ val apiSafetySourceData =
+ safetyCenterManager.getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)
+ assertThat(apiSafetySourceData).isEqualTo(safetySourceTestData.informationWithIssue)
+ }
+
+ @Test
+ fun refreshSafetySources_reasonPageOpen_allowedByFlagLater_broadcastSentLater() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.noPageOpenConfig)
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.information)
+ SafetySourceReceiver.setResponse(
+ Request.Refresh(SINGLE_SOURCE_ID),
+ Response.SetData(safetySourceTestData.informationWithIssue)
+ )
+
+ assertFailsWith(TimeoutCancellationException::class) {
+ safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
+ REFRESH_REASON_PAGE_OPEN,
+ timeout = TIMEOUT_SHORT
+ )
+ }
+ val apiSafetySourceDataBeforeSettingFlag =
+ safetyCenterManager.getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)
+ SafetyCenterFlags.overrideRefreshOnPageOpenSources = setOf(SINGLE_SOURCE_ID)
+ safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
+ REFRESH_REASON_PAGE_OPEN
+ )
+ val apiSafetySourceDataAfterSettingFlag =
+ safetyCenterManager.getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)
+
+ assertThat(apiSafetySourceDataBeforeSettingFlag).isEqualTo(safetySourceTestData.information)
+ assertThat(apiSafetySourceDataAfterSettingFlag)
+ .isEqualTo(safetySourceTestData.informationWithIssue)
+ }
+
+ @Test
+ fun refreshSafetySources_reasonPageOpen_noDataForSource_broadcastSent() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.noPageOpenConfig)
+ SafetySourceReceiver.setResponse(
+ Request.Refresh(SINGLE_SOURCE_ID),
+ Response.SetData(safetySourceTestData.information)
+ )
+
+ safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(
+ REFRESH_REASON_PAGE_OPEN
+ )
+
+ val apiSafetySourceData =
+ safetyCenterManager.getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)
+ assertThat(apiSafetySourceData).isEqualTo(safetySourceTestData.information)
+ }
+
+ @Test
fun getSafetyCenterData_withoutDataProvided_returnsDataFromConfig() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
@@ -874,28 +1007,105 @@ class SafetyCenterManagerTest {
}
@Test
+ fun getSafetyCenterData_withoutDataExplicitIntentConfig_defaultEntryHasExplicitIntent() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+
+ val apiSafetyCenterData = safetyCenterManager.getSafetyCenterDataWithPermission()
+
+ val expectedExplicitPendingIntent =
+ SafetySourceTestData.createRedirectPendingIntent(
+ context,
+ Intent(ACTION_TEST_ACTIVITY).setPackage(context.packageName)
+ )
+ val defaultEntryPendingIntent =
+ apiSafetyCenterData.entriesOrGroups.firstOrNull()?.entry?.pendingIntent
+ val defaultEntryIntentFilterEqualsToExplicitIntent =
+ callWithShellPermissionIdentity("android.permission.GET_INTENT_SENDER_INTENT") {
+ expectedExplicitPendingIntent.intentFilterEquals(defaultEntryPendingIntent)
+ }
+ assertThat(defaultEntryIntentFilterEqualsToExplicitIntent).isTrue()
+ }
+
+ @Test
fun getSafetyCenterData_withoutDataImplicitIntentConfig_defaultEntryHasImplicitIntent() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.implicitIntentSingleSourceConfig)
val apiSafetyCenterData = safetyCenterManager.getSafetyCenterDataWithPermission()
- val implicitPendingIntentCreatedByCts =
- PendingIntent.getActivity(
+ val expectedImplicitPendingIntent =
+ SafetySourceTestData.createRedirectPendingIntent(
context,
- 0 /* requestCode */,
- Intent(ACTION_TEST_ACTIVITY_EXPORTED),
- PendingIntent.FLAG_IMMUTABLE
+ Intent(ACTION_TEST_ACTIVITY_EXPORTED)
)
val defaultEntryPendingIntent =
apiSafetyCenterData.entriesOrGroups.firstOrNull()?.entry?.pendingIntent
val defaultEntryIntentFilterEqualsToImplicitIntent =
callWithShellPermissionIdentity("android.permission.GET_INTENT_SENDER_INTENT") {
- implicitPendingIntentCreatedByCts.intentFilterEquals(defaultEntryPendingIntent)
+ expectedImplicitPendingIntent.intentFilterEquals(defaultEntryPendingIntent)
}
assertThat(defaultEntryIntentFilterEqualsToImplicitIntent).isTrue()
}
@Test
+ fun getSafetyCenterData_withStaticImplicitResolving_implicitStaticEntry() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.staticSourcesConfig)
+
+ val apiSafetyCenterData = safetyCenterManager.getSafetyCenterDataWithPermission()
+
+ val expectedImplicitPendingIntent =
+ SafetySourceTestData.createRedirectPendingIntent(
+ context,
+ Intent(ACTION_TEST_ACTIVITY_EXPORTED)
+ )
+ val staticEntryPendingIntent =
+ apiSafetyCenterData.staticEntryGroups
+ .firstOrNull()
+ ?.staticEntries
+ ?.firstOrNull()
+ ?.pendingIntent
+ val staticEntryIntentFilterEqualsToImplicitIntent =
+ callWithShellPermissionIdentity("android.permission.GET_INTENT_SENDER_INTENT") {
+ expectedImplicitPendingIntent.intentFilterEquals(staticEntryPendingIntent)
+ }
+ assertThat(staticEntryIntentFilterEqualsToImplicitIntent).isTrue()
+ }
+
+ @Test
+ fun getSafetyCenterData_withStaticImplicitNotExported_explicitStaticEntryUsingCallerPackage() {
+ safetyCenterTestHelper.setConfig(
+ safetyCenterTestConfigs.singleStaticImplicitIntentNotExportedConfig
+ )
+
+ val apiSafetyCenterData = safetyCenterManager.getSafetyCenterDataWithPermission()
+
+ val expectedExplicitPendingIntent =
+ SafetySourceTestData.createRedirectPendingIntent(
+ context,
+ Intent(ACTION_TEST_ACTIVITY).setPackage(context.packageName)
+ )
+ val staticEntryPendingIntent =
+ apiSafetyCenterData.staticEntryGroups
+ .firstOrNull()
+ ?.staticEntries
+ ?.firstOrNull()
+ ?.pendingIntent
+ val staticEntryIntentFilterEqualsToExplicitIntent =
+ callWithShellPermissionIdentity("android.permission.GET_INTENT_SENDER_INTENT") {
+ expectedExplicitPendingIntent.intentFilterEquals(staticEntryPendingIntent)
+ }
+ assertThat(staticEntryIntentFilterEqualsToExplicitIntent).isTrue()
+ }
+
+ @Test
+ fun getSafetyCenterData_withStaticNotResolving_noStaticEntry() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleStaticInvalidIntentConfig)
+
+ val apiSafetyCenterData = safetyCenterManager.getSafetyCenterDataWithPermission()
+
+ assertThat(apiSafetyCenterData.staticEntryGroups).isEmpty()
+ }
+
+ @Test
fun getSafetyCenterData_withComplexConfigWithoutDataProvided_returnsDataFromConfig() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexConfig)
@@ -940,7 +1150,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_attributionTitleProvidedBySource_returnsIssueWithAttributionTitle() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
safetyCenterTestHelper.setData(
@@ -956,7 +1166,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_attributionTitleNotProvided_returnsGroupTitleAsAttributionTitle() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue)
@@ -969,7 +1179,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_attributionNotSetAndGroupTitleNull_returnsNullAttributionTitle() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceNoGroupTitleConfig)
safetyCenterTestHelper.setData(
@@ -997,9 +1207,6 @@ class SafetyCenterManagerTest {
@Test
@SdkSuppress(maxSdkVersion = TIRAMISU)
fun getSafetyCenterData_attributionNotSetBySourceOnTiramisu_returnsNullAttributionTitle() {
- // TODO(b/258228790): Remove after U is no longer in pre-release
- assumeFalse(Build.VERSION.CODENAME == "UpsideDownCake")
- assumeFalse(Build.VERSION.CODENAME == "VanillaIceCream")
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue)
@@ -1074,7 +1281,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withActionConfirmation_returnsRecommendationWithActionConfirmation() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
safetyCenterTestHelper.setData(
@@ -1154,7 +1361,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withRecommendationDataIssue_returnsDataRecommendationStatus() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1179,7 +1386,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withCriticalDataIssue_returnsDataCriticalStatus() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1204,7 +1411,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withRecommendationPasswordsIssue_returnsDataRecommendationStatus() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1229,7 +1436,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withCriticalPasswordsIssue_returnsDataCriticalStatus() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1254,7 +1461,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withRecommendationPersonalIssue_returnsDataRecommendationStatus() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1279,7 +1486,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withCriticalPersonalIssue_returnsDataCriticalStatus() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1304,7 +1511,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_infoStatusTipFirstIssueSingleTip_infoStatusWithTipSummary() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1324,7 +1531,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_infoStatusTipFirstIssueMultiTips_infoStatusWithTipsSummary() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1360,7 +1567,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_infoStatusActionFirstIssueSingleAction_infoStatusWithActionSummary() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1380,7 +1587,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_infoStatusActionFirstIssueMultiActions_infoStatusWithActionsSummary() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1416,7 +1623,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_infoStatusManualFirstIssueSingleManual_infoStatusWithAlertSummary() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1442,7 +1649,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_infoStatusManualFirstIssueMultiManual_infoStatusWithAlertsSummary() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.issueOnlySourceConfig)
safetyCenterTestHelper.setData(
@@ -1480,7 +1687,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_withStaticEntryGroups_hasStaticEntriesToIdsMapping() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.staticSourcesConfig)
@@ -1560,7 +1767,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesOfSameSeverities_issueOfFirstSourceInConfigShown() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1592,7 +1799,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesInDifferentSourceGroups_topIssueRelevantForBothGroups() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1622,7 +1829,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesInSameSourceGroups_topIssueRelevantForThatGroup() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1652,7 +1859,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_noDuplicateIssues_noGroupBelongingSpecified() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1680,7 +1887,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_differentDuplicationId_bothIssuesShown() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1717,7 +1924,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_differentDuplicationGroup_bothIssuesShown() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1754,7 +1961,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_threeDuplicateIssues_onlyOneIssueShown() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1793,7 +2000,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesOfDifferentSeverities_moreSevereIssueShown() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1825,7 +2032,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_multipleDuplicationsOfIssues_correctlyDeduplicated() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1901,7 +2108,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesBothDismissed_topOneShownAsDismissed() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1942,7 +2149,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesLowerSeverityOneDismissed_topOneShown() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -1980,7 +2187,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesHigherSeverityOneDismissed_topOneShownAsDismissed() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -2018,7 +2225,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_dupIssuesLowerPrioritySameSeverityOneDismissed_topShownAsDismissed() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -2056,7 +2263,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_dupIssuesTopOneDismissedThenDisappears_bottomOneReemergesTimely() {
SafetyCenterFlags.tempHiddenIssueResurfaceDelay = Duration.ZERO
SafetyCenterFlags.resurfaceIssueMaxCounts = mapOf(SEVERITY_LEVEL_CRITICAL_WARNING to 99L)
@@ -2110,7 +2317,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_dupsOfDiffSeveritiesTopOneDismissedThenGone_bottomOneReemergesTimely() {
SafetyCenterFlags.tempHiddenIssueResurfaceDelay = Duration.ZERO
SafetyCenterFlags.resurfaceIssueMaxCounts =
@@ -2173,7 +2380,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesLowerOneResurfaces_lowerOneStillFilteredOut() {
SafetyCenterFlags.resurfaceIssueMaxCounts =
mapOf(
@@ -2236,7 +2443,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_duplicateIssuesTopOneResurfaces_topOneShown() {
SafetyCenterFlags.resurfaceIssueMaxCounts =
mapOf(
@@ -2297,7 +2504,7 @@ class SafetyCenterManagerTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun getSafetyCenterData_dupIssuesTopOneResolved_bottomOneReemergesAfterTemporaryHiddenPeriod() {
SafetyCenterFlags.tempHiddenIssueResurfaceDelay = RESURFACE_DELAY
safetyCenterTestHelper.setConfig(
@@ -2831,7 +3038,7 @@ class SafetyCenterManagerTest {
safetyCenterManager.getSafetyCenterDataWithPermission().getGroup(SUMMARY_TEST_GROUP_ID)
assertThat(group.summary)
- .isEqualTo(safetyCenterResourcesContext.getStringByName("group_unknown_summary"))
+ .isEqualTo(safetyCenterResourcesApk.getStringByName("group_unknown_summary"))
assertThat(group.severityLevel).isEqualTo(ENTRY_SEVERITY_LEVEL_UNKNOWN)
}
@@ -2845,7 +3052,7 @@ class SafetyCenterManagerTest {
.getGroup(ANDROID_LOCK_SCREEN_SOURCES_GROUP_ID)
assertThat(initialGroup.summary)
- .isEqualTo(safetyCenterResourcesContext.getStringByName("group_unknown_summary"))
+ .isEqualTo(safetyCenterResourcesApk.getStringByName("group_unknown_summary"))
assertThat(initialGroup.severityLevel).isEqualTo(ENTRY_SEVERITY_LEVEL_UNKNOWN)
safetyCenterTestHelper.setData(DYNAMIC_BAREBONE_ID, safetySourceTestData.unspecified)
@@ -3340,7 +3547,7 @@ class SafetyCenterManagerTest {
assertThat(error)
.isEqualTo(
SafetyCenterErrorDetails(
- safetyCenterResourcesContext.getStringByName("resolving_action_error")
+ safetyCenterResourcesApk.getStringByName("resolving_action_error")
)
)
}
@@ -3374,7 +3581,7 @@ class SafetyCenterManagerTest {
assertThat(error)
.isEqualTo(
SafetyCenterErrorDetails(
- safetyCenterResourcesContext.getStringByName("resolving_action_error")
+ safetyCenterResourcesApk.getStringByName("resolving_action_error")
)
)
}
@@ -3538,46 +3745,6 @@ class SafetyCenterManagerTest {
}
@Test
- fun lockScreenSource_withoutReplaceLockScreenIconActionFlag_doesntReplace() {
- // Must have a screen lock for the icon action to be set
- assumeTrue(ScreenLockHelper.isDeviceSecure(context))
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.settingsLockScreenSourceConfig)
- val listener = safetyCenterTestHelper.addListener()
- SafetyCenterFlags.replaceLockScreenIconAction = false
-
- safetyCenterManager.refreshSafetySourcesWithPermission(REFRESH_REASON_PAGE_OPEN)
- // Skip loading data.
- listener.receiveSafetyCenterData()
-
- val lockScreenSafetyCenterData = listener.receiveSafetyCenterData()
- val lockScreenEntry = lockScreenSafetyCenterData.entriesOrGroups.first().entry!!
- val entryPendingIntent = lockScreenEntry.pendingIntent!!
- val iconActionPendingIntent = lockScreenEntry.iconAction!!.pendingIntent
- // This test passes for now but will eventually start failing once we introduce the fix in
- // the Settings app. This will warn if the assumption is failed rather than fail, at which
- // point we can remove this test (and potentially even this magnificent hack).
- assumeTrue(iconActionPendingIntent == entryPendingIntent)
- }
-
- @Test
- fun lockScreenSource_withReplaceLockScreenIconActionFlag_replaces() {
- // Must have a screen lock for the icon action to be set
- assumeTrue(ScreenLockHelper.isDeviceSecure(context))
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.settingsLockScreenSourceConfig)
- val listener = safetyCenterTestHelper.addListener()
-
- safetyCenterManager.refreshSafetySourcesWithPermission(REFRESH_REASON_PAGE_OPEN)
- // Skip loading data.
- listener.receiveSafetyCenterData()
-
- val lockScreenSafetyCenterData = listener.receiveSafetyCenterData()
- val lockScreenEntry = lockScreenSafetyCenterData.entriesOrGroups.first().entry!!
- val entryPendingIntent = lockScreenEntry.pendingIntent!!
- val iconActionPendingIntent = lockScreenEntry.iconAction!!.pendingIntent
- assertThat(iconActionPendingIntent).isNotEqualTo(entryPendingIntent)
- }
-
- @Test
fun beforeAnyDataSet_noLastUpdatedTimestamps() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt
index 70d6468fa..9c9e9b009 100644
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterNotificationTest.kt
@@ -28,19 +28,21 @@ import android.safetycenter.SafetyCenterStatus
import android.safetycenter.SafetyEvent
import android.safetycenter.SafetySourceErrorDetails
import android.safetycenter.SafetySourceIssue
-import android.safetycenter.functional.testing.NotificationCharacteristics
-import android.safetycenter.functional.testing.TestNotificationListener
+import android.service.notification.StatusBarNotification
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
+import com.android.compatibility.common.util.DisableAnimationRule
+import com.android.compatibility.common.util.FreezeRotationRule
import com.android.safetycenter.pendingintents.PendingIntentSender
+import com.android.safetycenter.testing.Coroutines
import com.android.safetycenter.testing.Coroutines.TIMEOUT_SHORT
+import com.android.safetycenter.testing.NotificationCharacteristics
import com.android.safetycenter.testing.SafetyCenterActivityLauncher.executeBlockAndExit
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.clearAllSafetySourceDataForTestsWithPermission
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.dismissSafetyCenterIssueWithPermission
import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.reportSafetySourceErrorWithPermission
import com.android.safetycenter.testing.SafetyCenterFlags
-import com.android.safetycenter.testing.SafetyCenterFlags.deviceSupportsSafetyCenter
import com.android.safetycenter.testing.SafetyCenterTestConfigs
import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID
import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_1
@@ -48,20 +50,23 @@ import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE
import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_5
import com.android.safetycenter.testing.SafetyCenterTestData
import com.android.safetycenter.testing.SafetyCenterTestHelper
+import com.android.safetycenter.testing.SafetyCenterTestRule
import com.android.safetycenter.testing.SafetySourceIntentHandler.Request
import com.android.safetycenter.testing.SafetySourceIntentHandler.Response
import com.android.safetycenter.testing.SafetySourceReceiver
import com.android.safetycenter.testing.SafetySourceTestData
import com.android.safetycenter.testing.SafetySourceTestData.Companion.ISSUE_TYPE_ID
import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
+import com.android.safetycenter.testing.StatusBarNotificationWithChannel
+import com.android.safetycenter.testing.SupportsSafetyCenterRule
+import com.android.safetycenter.testing.TestNotificationListener
import com.android.safetycenter.testing.UiTestHelper.waitSourceIssueDisplayed
import com.google.common.truth.Truth.assertThat
import java.time.Duration
import kotlin.test.assertFailsWith
import kotlinx.coroutines.TimeoutCancellationException
-import org.junit.After
-import org.junit.Assume.assumeTrue
import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -74,41 +79,23 @@ class SafetyCenterNotificationTest {
private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
private val safetyCenterManager =
requireNotNull(context.getSystemService(SafetyCenterManager::class.java)) {
- "Could not get system service"
+ "Could not get SafetyCenterManager"
}
- // JUnit's Assume is not supported in @BeforeClass by the CTS tests runner, so this is used to
- // manually skip the setup and teardown methods.
- private val shouldRunTests = context.deviceSupportsSafetyCenter()
+ @get:Rule(order = 1) val supportsSafetyCenterRule = SupportsSafetyCenterRule(context)
+ @get:Rule(order = 2)
+ val safetyCenterTestRule =
+ SafetyCenterTestRule(safetyCenterTestHelper, withNotifications = true)
+ @get:Rule(order = 3) val disableAnimationRule = DisableAnimationRule()
+ @get:Rule(order = 4) val freezeRotationRule = FreezeRotationRule()
@Before
- fun assumeDeviceSupportsSafetyCenterToRunTests() {
- assumeTrue(shouldRunTests)
- }
-
- @Before
- fun setUp() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.setup()
- TestNotificationListener.setup()
+ fun enableNotificationsForTestSourceBeforeTest() {
SafetyCenterFlags.notificationsEnabled = true
setFlagsForImmediateNotifications(SINGLE_SOURCE_ID)
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
}
- @After
- fun tearDown() {
- if (!shouldRunTests) {
- return
- }
- // It is important to reset the notification listener last because it waits/ensures that
- // all notifications have been removed before returning.
- safetyCenterTestHelper.reset()
- TestNotificationListener.reset()
- }
-
@Test
fun setSafetySourceData_withNoIssue_noNotification() {
safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.information)
@@ -153,7 +140,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withNotificationBehaviorNever_noNotification() {
val data =
safetySourceTestData
@@ -172,7 +159,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withNotificationBehaviorDelay_noImmediateNotification() {
SafetyCenterFlags.notificationsMinDelay = Duration.ofDays(1)
val data =
@@ -192,7 +179,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withNotificationBehaviorDelay_sendsNotificationAfterDelay() {
SafetyCenterFlags.notificationsMinDelay = Duration.ofDays(1)
val delayedNotificationIssue =
@@ -237,7 +224,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withNotificationBehaviorDelayOfZero_sendsNotificationImmediately() {
SafetyCenterFlags.immediateNotificationBehaviorIssues = emptySet()
SafetyCenterFlags.notificationsMinDelay = Duration.ofSeconds(0)
@@ -264,7 +251,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withNotificationBehaviorImmediately_sendsNotification() {
SafetyCenterFlags.immediateNotificationBehaviorIssues = emptySet()
val data =
@@ -309,8 +296,8 @@ class SafetyCenterNotificationTest {
@Test
fun setSafetySourceData_issueWithTwoActions_notificationWithTwoActions() {
- val intent1 = safetySourceTestData.testActivityRedirectPendingIntent(identifier = "1")
- val intent2 = safetySourceTestData.testActivityRedirectPendingIntent(identifier = "2")
+ val intent1 = safetySourceTestData.createTestActivityRedirectPendingIntent(identifier = "1")
+ val intent2 = safetySourceTestData.createTestActivityRedirectPendingIntent(identifier = "2")
val data =
safetySourceTestData
@@ -341,7 +328,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withNotificationsAllowedForSourceByConfig_sendsNotification() {
SafetyCenterFlags.notificationsAllowedSources = emptySet()
SafetyCenterFlags.immediateNotificationBehaviorIssues = emptySet()
@@ -372,10 +359,10 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withCustomNotification_usesCustomValues() {
- val intent1 = safetySourceTestData.testActivityRedirectPendingIntent(identifier = "1")
- val intent2 = safetySourceTestData.testActivityRedirectPendingIntent(identifier = "2")
+ val intent1 = safetySourceTestData.createTestActivityRedirectPendingIntent(identifier = "1")
+ val intent2 = safetySourceTestData.createTestActivityRedirectPendingIntent(identifier = "2")
val notification =
SafetySourceIssue.Notification.Builder("Custom title", "Custom text")
@@ -397,7 +384,7 @@ class SafetyCenterNotificationTest {
SafetySourceIssue.Action.Builder(
"default_action",
"Default action",
- safetySourceTestData.testActivityRedirectPendingIntent
+ safetySourceTestData.createTestActivityRedirectPendingIntent()
)
.build()
)
@@ -418,7 +405,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_withEmptyCustomActions_notificationHasNoActions() {
val notification =
SafetySourceIssue.Notification.Builder("Custom title", "Custom text")
@@ -435,7 +422,7 @@ class SafetyCenterNotificationTest {
SafetySourceIssue.Action.Builder(
"default_action",
"Default action",
- safetySourceTestData.testActivityRedirectPendingIntent
+ safetySourceTestData.createTestActivityRedirectPendingIntent()
)
.build()
)
@@ -488,7 +475,7 @@ class SafetyCenterNotificationTest {
SafetySourceIssue.Action.Builder(
"new_action",
"New action",
- safetySourceTestData.testActivityRedirectPendingIntent(
+ safetySourceTestData.createTestActivityRedirectPendingIntent(
identifier = "new_action"
)
)
@@ -539,6 +526,22 @@ class SafetyCenterNotificationTest {
TestNotificationListener.waitForZeroNotifications()
}
+ // TODO(b/284271124): Decide what to do with existing notifications when flag flipped off
+ @Test
+ fun setSafetySourceData_removingAnIssue_afterFlagTurnedOff_noNotificationChanges() {
+ val data1 = safetySourceTestData.recommendationWithAccountIssue
+ val data2 = safetySourceTestData.information
+
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data1)
+
+ TestNotificationListener.waitForSingleNotification()
+
+ SafetyCenterFlags.notificationsEnabled = false
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data2)
+
+ TestNotificationListener.waitForZeroNotificationEvents()
+ }
+
@Test
fun reportSafetySourceError_sourceWithNotification_cancelsNotification() {
val data = safetySourceTestData.recommendationWithAccountIssue
@@ -630,7 +633,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_duplicateIssues_sendsOneNotification() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -660,7 +663,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun setSafetySourceData_duplicateIssueOfLowerSeverityDismissed_sendsNotification() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -784,7 +787,7 @@ class SafetyCenterNotificationTest {
}
@Test
- @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
fun dismissingNotification_withDuplicateIssues_allDismissed() {
safetyCenterTestHelper.setConfig(
safetyCenterTestConfigs.multipleSourcesWithDeduplicationInfoConfig
@@ -898,13 +901,135 @@ class SafetyCenterNotificationTest {
sendActionPendingIntentAndWaitWithPermission(action)
- TestNotificationListener.waitForSingleNotificationMatching(
- NotificationCharacteristics(
- "Issue solved",
- "",
- actions = emptyList(),
+ TestNotificationListener.waitForSuccessNotification("Issue solved")
+ }
+
+ @Test
+ fun successNotification_notificationHasAutoCancel() {
+ safetyCenterTestHelper.setData(
+ SINGLE_SOURCE_ID,
+ safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage
+ )
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
+ val action =
+ notificationWithChannel.statusBarNotification.notification.actions.firstOrNull()
+ checkNotNull(action) { "Notification action unexpectedly null" }
+ SafetySourceReceiver.setResponse(
+ Request.ResolveAction(SINGLE_SOURCE_ID),
+ Response.SetData(safetySourceTestData.information)
+ )
+ sendActionPendingIntentAndWaitWithPermission(action)
+
+ TestNotificationListener.waitForSuccessNotification("Issue solved") {
+ assertThat(it.hasAutoCancel()).isTrue()
+ }
+ }
+
+ // TODO(b/284271124): Decide what to do with existing notifications when flag flipped off
+ @Test
+ fun sendActionPendingIntent_flagDisabled_pendingIntentNotSentToSource() {
+ safetyCenterTestHelper.setData(
+ SINGLE_SOURCE_ID,
+ safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage
+ )
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
+ val action =
+ notificationWithChannel.statusBarNotification.notification.actions.firstOrNull()
+ checkNotNull(action) { "Notification action unexpectedly null" }
+ SafetySourceReceiver.setResponse(
+ Request.ResolveAction(SINGLE_SOURCE_ID),
+ Response.SetData(safetySourceTestData.information)
+ )
+ SafetyCenterFlags.notificationsEnabled = false
+
+ assertFailsWith(TimeoutCancellationException::class) {
+ sendActionPendingIntentAndWaitWithPermission(action, timeout = TIMEOUT_SHORT)
+ }
+ }
+
+ @Test
+ fun sendActionPendingIntent_sourceStateChangedSafetyEvent_successNotification() {
+ safetyCenterTestHelper.setData(
+ SINGLE_SOURCE_ID,
+ safetySourceTestData.criticalWithResolvingIssueWithSuccessMessage
+ )
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
+ val action =
+ notificationWithChannel.statusBarNotification.notification.actions.firstOrNull()
+ checkNotNull(action) { "Notification action unexpectedly null" }
+ SafetySourceReceiver.setResponse(
+ Request.ResolveAction(SINGLE_SOURCE_ID),
+ Response.SetData(
+ safetySourceTestData.information,
+ overrideSafetyEvent =
+ SafetyEvent.Builder(SafetyEvent.SAFETY_EVENT_TYPE_SOURCE_STATE_CHANGED).build()
)
)
+
+ sendActionPendingIntentAndWaitWithPermission(action)
+
+ TestNotificationListener.waitForSuccessNotification("Issue solved")
+ }
+
+ @Test
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
+ fun sendActionPendingIntent_actionIdDiffersFromIssueActionId_successNotification() {
+ val notification =
+ SafetySourceIssue.Notification.Builder("Custom title", "Custom text")
+ .addAction(
+ SafetySourceIssue.Action.Builder(
+ "notification_action_id",
+ "Solve now!",
+ safetySourceTestData.resolvingActionPendingIntent(
+ sourceIssueActionId = "notification_action_id"
+ )
+ )
+ .setWillResolve(true)
+ .setSuccessMessage("Solved via notification action :)")
+ .build()
+ )
+ .build()
+ val data =
+ safetySourceTestData
+ .defaultCriticalDataBuilder()
+ .clearIssues()
+ .addIssue(
+ safetySourceTestData
+ .defaultCriticalResolvingIssueBuilder()
+ .clearActions()
+ .addAction(
+ SafetySourceIssue.Action.Builder(
+ "issue_action_id",
+ "Default action",
+ safetySourceTestData.resolvingActionPendingIntent(
+ sourceIssueActionId = "issue_action_id"
+ )
+ )
+ .setWillResolve(true)
+ .setSuccessMessage("Solved via issue action :(")
+ .build()
+ )
+ .setCustomNotification(notification)
+ .setNotificationBehavior(
+ SafetySourceIssue.NOTIFICATION_BEHAVIOR_IMMEDIATELY
+ )
+ .build()
+ )
+ .build()
+
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, data)
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
+ val action =
+ notificationWithChannel.statusBarNotification.notification.actions.firstOrNull()
+ checkNotNull(action) { "Notification action unexpectedly null" }
+ SafetySourceReceiver.setResponse(
+ Request.ResolveAction(SINGLE_SOURCE_ID),
+ Response.SetData(safetySourceTestData.information)
+ )
+
+ sendActionPendingIntentAndWaitWithPermission(action)
+
+ TestNotificationListener.waitForSuccessNotification("Solved via notification action :)")
}
@Test
@@ -941,12 +1066,10 @@ class SafetyCenterNotificationTest {
safetySourceTestData.recommendationWithDeviceIssue
)
val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
- val contentIntent = notificationWithChannel.statusBarNotification.notification.contentIntent
- executeBlockAndExit(
- launchActivity = { PendingIntentSender.send(contentIntent) },
- block = { waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue) }
- )
+ sendContentPendingIntent(notificationWithChannel) {
+ waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue)
+ }
}
@Test
@@ -962,34 +1085,69 @@ class SafetyCenterNotificationTest {
safetySourceTestData.criticalWithResolvingGeneralIssue
)
val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
- val contentIntent = notificationWithChannel.statusBarNotification.notification.contentIntent
- executeBlockAndExit(
- launchActivity = { PendingIntentSender.send(contentIntent) },
- block = {
- waitSourceIssueDisplayed(safetySourceTestData.criticalResolvingGeneralIssue)
- waitSourceIssueDisplayed(safetySourceTestData.recommendationGeneralIssue)
- }
+ sendContentPendingIntent(notificationWithChannel) {
+ waitSourceIssueDisplayed(safetySourceTestData.criticalResolvingGeneralIssue)
+ waitSourceIssueDisplayed(safetySourceTestData.recommendationDeviceIssue)
+ }
+ }
+
+ @Test
+ fun whenGreenIssue_notificationHasAutoCancel() {
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue)
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
+
+ assertThat(notificationWithChannel.statusBarNotification.hasAutoCancel()).isTrue()
+ }
+
+ @Test
+ fun whenNotGreenIssue_notificationDoesntHaveAutoCancel() {
+ safetyCenterTestHelper.setData(
+ SINGLE_SOURCE_ID,
+ safetySourceTestData.recommendationWithDeviceIssue
)
+ val notificationWithChannel = TestNotificationListener.waitForSingleNotification()
+
+ assertThat(notificationWithChannel.statusBarNotification.hasAutoCancel()).isFalse()
}
- companion object {
- private val SafetyCenterData.inFlightActions: List<SafetyCenterIssue.Action>
+ private companion object {
+ val SafetyCenterData.inFlightActions: List<SafetyCenterIssue.Action>
get() = issues.flatMap { it.actions }.filter { it.isInFlight }
- private fun sendActionPendingIntentAndWaitWithPermission(action: Notification.Action) {
+ fun sendActionPendingIntentAndWaitWithPermission(
+ action: Notification.Action,
+ timeout: Duration = Coroutines.TIMEOUT_LONG
+ ) {
callWithShellPermissionIdentity(SEND_SAFETY_CENTER_UPDATE) {
PendingIntentSender.send(action.actionIntent)
// Sending the action's PendingIntent above is asynchronous and we need to wait for
// it to be received by the fake receiver below.
- SafetySourceReceiver.receiveResolveAction()
+ SafetySourceReceiver.receiveResolveAction(timeout)
}
}
- private fun setFlagsForImmediateNotifications(vararg sourceIds: String) {
+ fun setFlagsForImmediateNotifications(vararg sourceIds: String) {
SafetyCenterFlags.notificationsAllowedSources = sourceIds.toSet()
SafetyCenterFlags.immediateNotificationBehaviorIssues =
sourceIds.map { "$it/$ISSUE_TYPE_ID" }.toSet()
}
+
+ fun StatusBarNotification.hasAutoCancel(): Boolean {
+ val autoCancelMask = notification.flags and Notification.FLAG_AUTO_CANCEL
+ return autoCancelMask != 0
+ }
+
+ fun sendContentPendingIntent(
+ statusBarNotificationWithChannel: StatusBarNotificationWithChannel,
+ andExecuteBlock: () -> Unit = {}
+ ) {
+ val contentIntent =
+ statusBarNotificationWithChannel.statusBarNotification.notification.contentIntent
+ executeBlockAndExit(
+ launchActivity = { PendingIntentSender.send(contentIntent) },
+ block = andExecuteBlock
+ )
+ }
}
}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterShellCommandsTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterShellCommandsTest.kt
new file mode 100644
index 000000000..7c5b41944
--- /dev/null
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetyCenterShellCommandsTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.safetycenter.functional
+
+import android.Manifest.permission.INTERACT_ACROSS_USERS
+import android.app.ActivityManager
+import android.content.Context
+import android.safetycenter.SafetyCenterManager
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compatibility.common.util.SystemUtil
+import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.isSafetyCenterEnabledWithPermission
+import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
+import com.android.safetycenter.testing.deviceSupportsSafetyCenter
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Tests for Safety Center's shell commands. */
+@RunWith(AndroidJUnit4::class)
+class SafetyCenterShellCommandsTest {
+ private val context: Context = getApplicationContext()
+
+ @Test
+ fun enabled_printsEnabledValue() {
+ val enabled = executeShellCommand("cmd safety_center enabled").toBoolean()
+
+ val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java)!!
+ assertThat(enabled).isEqualTo(safetyCenterManager.isSafetyCenterEnabledWithPermission())
+ }
+
+ @Test
+ fun supported_printsSupportedValue() {
+ val supported = executeShellCommand("cmd safety_center supported").toBoolean()
+
+ assertThat(supported).isEqualTo(context.deviceSupportsSafetyCenter())
+ }
+
+ @Test
+ fun packageName_printsPackageName() {
+ val packageName = executeShellCommand("cmd safety_center package-name")
+
+ assertThat(packageName).isEqualTo(context.packageManager.permissionControllerPackageName)
+ }
+
+ @Test
+ fun clearData_executesSuccessfully() {
+ executeShellCommand("cmd safety_center clear-data")
+ }
+
+ @Test
+ fun refresh_executesSuccessfully() {
+ val currentUser =
+ callWithShellPermissionIdentity(INTERACT_ACROSS_USERS) {
+ ActivityManager.getCurrentUser()
+ }
+ executeShellCommand("cmd safety_center refresh --reason OTHER --user $currentUser")
+ }
+
+ @Test
+ fun help_containsAllCommands() {
+ val help = executeShellCommand("cmd safety_center help")
+
+ assertThat(help).contains("help")
+ assertThat(help).contains("enabled")
+ assertThat(help).contains("supported")
+ assertThat(help).contains("package-name")
+ assertThat(help).contains("clear-data")
+ assertThat(help).contains("refresh")
+ }
+
+ @Test
+ fun dump_containsSafetyCenterService() {
+ val dump = executeShellCommand("dumpsys safety_center")
+
+ assertThat(dump).contains("SafetyCenterService")
+ }
+
+ private fun executeShellCommand(command: String): String =
+ SystemUtil.runShellCommandOrThrow(command).trim()
+}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetySourceDataFixesTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetySourceDataFixesTest.kt
new file mode 100644
index 000000000..4ba293eb9
--- /dev/null
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/SafetySourceDataFixesTest.kt
@@ -0,0 +1,298 @@
+package android.safetycenter.functional
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE
+import android.safetycenter.SafetyCenterManager
+import android.safetycenter.SafetySourceData
+import android.safetycenter.SafetySourceData.SEVERITY_LEVEL_INFORMATION
+import android.safetycenter.SafetySourceIssue
+import android.safetycenter.SafetySourceStatus
+import androidx.annotation.RequiresApi
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SdkSuppress
+import com.android.compatibility.common.preconditions.ScreenLockHelper
+import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.getSafetySourceDataWithPermission
+import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.refreshSafetySourcesWithPermission
+import com.android.safetycenter.testing.SafetyCenterFlags
+import com.android.safetycenter.testing.SafetyCenterTestConfigs
+import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID
+import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_1
+import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_2
+import com.android.safetycenter.testing.SafetyCenterTestHelper
+import com.android.safetycenter.testing.SafetyCenterTestRule
+import com.android.safetycenter.testing.SafetySourceTestData
+import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
+import com.android.safetycenter.testing.SupportsSafetyCenterRule
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assume.assumeTrue
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Functional tests for "fixes" applied to Safety Source data received by [SafetyCenterManager]. */
+@RunWith(AndroidJUnit4::class)
+class SafetySourceDataFixesTest {
+
+ private val context: Context = ApplicationProvider.getApplicationContext()
+ private val safetyCenterTestHelper = SafetyCenterTestHelper(context)
+ private val safetySourceTestData = SafetySourceTestData(context)
+ private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
+ private val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java)!!
+
+ @get:Rule(order = 1) val supportsSafetyCenterRule = SupportsSafetyCenterRule(context)
+ @get:Rule(order = 2) val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper)
+
+ @Test
+ fun lockScreenSource_withoutReplaceLockScreenIconActionFlag_doesntReplace() {
+ // Must have a screen lock for the icon action to be set
+ assumeTrue(ScreenLockHelper.isDeviceSecure(context))
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.settingsLockScreenSourceConfig)
+ val listener = safetyCenterTestHelper.addListener()
+ SafetyCenterFlags.replaceLockScreenIconAction = false
+
+ safetyCenterManager.refreshSafetySourcesWithPermission(
+ SafetyCenterManager.REFRESH_REASON_PAGE_OPEN
+ )
+ // Skip loading data.
+ listener.receiveSafetyCenterData()
+
+ val lockScreenSafetyCenterData = listener.receiveSafetyCenterData()
+ val lockScreenEntry = lockScreenSafetyCenterData.entriesOrGroups.first().entry!!
+ val entryPendingIntent = lockScreenEntry.pendingIntent!!
+ val iconActionPendingIntent = lockScreenEntry.iconAction!!.pendingIntent
+ // This test passes for now but will eventually start failing once we introduce the fix in
+ // the Settings app. This will warn if the assumption is failed rather than fail, at which
+ // point we can remove this test (and potentially even this magnificent hack).
+ assumeTrue(iconActionPendingIntent == entryPendingIntent)
+ }
+
+ @Test
+ fun lockScreenSource_withReplaceLockScreenIconActionFlag_replaces() {
+ // Must have a screen lock for the icon action to be set
+ assumeTrue(ScreenLockHelper.isDeviceSecure(context))
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.settingsLockScreenSourceConfig)
+ val listener = safetyCenterTestHelper.addListener()
+
+ safetyCenterManager.refreshSafetySourcesWithPermission(
+ SafetyCenterManager.REFRESH_REASON_PAGE_OPEN
+ )
+ // Skip loading data.
+ listener.receiveSafetyCenterData()
+
+ val lockScreenSafetyCenterData = listener.receiveSafetyCenterData()
+ val lockScreenEntry = lockScreenSafetyCenterData.entriesOrGroups.first().entry!!
+ val entryPendingIntent = lockScreenEntry.pendingIntent!!
+ val iconActionPendingIntent = lockScreenEntry.iconAction!!.pendingIntent
+ assertThat(iconActionPendingIntent).isNotEqualTo(entryPendingIntent)
+ }
+
+ @Test
+ fun defaultActionOverride_issue_overridesMatchingActions() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ val targetActionId = "TargetActionId"
+ SafetyCenterFlags.actionsToOverrideWithDefaultIntent =
+ mapOf(SINGLE_SOURCE_ID to setOf(targetActionId, "AdditionalActionId"))
+
+ val originalPendingIntent = pendingIntent(Intent("blah.wrong.INTENT"))
+ val dataWithActionToOverride =
+ sourceDataBuilder()
+ .addIssue(
+ issueBuilder()
+ .clearActions()
+ .addAction(
+ safetySourceTestData.action(
+ id = targetActionId,
+ pendingIntent = originalPendingIntent
+ )
+ )
+ .build()
+ )
+ .build()
+
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, dataWithActionToOverride)
+
+ val overriddenPendingIntent =
+ safetyCenterManager
+ .getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)!!
+ .issues[0]
+ .actions[0]
+ .pendingIntent
+ val expectedPendingIntent =
+ pendingIntent(
+ Intent(SafetyCenterTestConfigs.ACTION_TEST_ACTIVITY).setPackage(context.packageName)
+ )
+ assertThat(intentsFilterEqual(overriddenPendingIntent, expectedPendingIntent)).isTrue()
+ }
+ @Test
+ @SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE)
+ fun defaultActionOverride_notification_overridesMatchingActions() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ val targetActionId = "TargetActionId"
+ SafetyCenterFlags.actionsToOverrideWithDefaultIntent =
+ mapOf(SINGLE_SOURCE_ID to setOf(targetActionId, "AdditionalActionId"))
+
+ val originalPendingIntent = pendingIntent(Intent("blah.wrong.INTENT"))
+ val dataWithNotificationActionToOverride =
+ sourceDataBuilder()
+ .addIssue(
+ issueBuilder()
+ .setCustomNotification(
+ notification(
+ safetySourceTestData.action(
+ id = targetActionId,
+ pendingIntent = originalPendingIntent
+ )
+ )
+ )
+ .build()
+ )
+ .build()
+
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, dataWithNotificationActionToOverride)
+
+ val overriddenPendingIntent =
+ safetyCenterManager
+ .getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)!!
+ .issues[0]
+ .customNotification!!
+ .actions[0]
+ .pendingIntent
+ val expectedPendingIntent =
+ pendingIntent(
+ Intent(SafetyCenterTestConfigs.ACTION_TEST_ACTIVITY).setPackage(context.packageName)
+ )
+ assertThat(intentsFilterEqual(overriddenPendingIntent, expectedPendingIntent)).isTrue()
+ }
+
+ @Test
+ fun defaultActionOverride_sameActionIdDifferentSource_doesNotOverride() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
+ val targetActionId = "TargetActionId"
+ SafetyCenterFlags.actionsToOverrideWithDefaultIntent =
+ mapOf(SOURCE_ID_1 to setOf(targetActionId, "AdditionalActionId"))
+
+ val originalPendingIntent = pendingIntent(Intent("blah.wrong.INTENT"))
+ val dataWithoutActionToOverride =
+ sourceDataBuilder()
+ .addIssue(
+ issueBuilder()
+ .clearActions()
+ .addAction(
+ safetySourceTestData.action(
+ id = targetActionId,
+ pendingIntent = originalPendingIntent
+ )
+ )
+ .build()
+ )
+ .build()
+
+ safetyCenterTestHelper.setData(
+ SOURCE_ID_2, // Different source ID
+ dataWithoutActionToOverride
+ )
+
+ val actualPendingIntent =
+ safetyCenterManager
+ .getSafetySourceDataWithPermission(SOURCE_ID_2)!!
+ .issues[0]
+ .actions[0]
+ .pendingIntent
+ assertThat(intentsFilterEqual(actualPendingIntent, originalPendingIntent)).isTrue()
+ }
+
+ @Test
+ fun defaultActionOverride_sameSourceDifferentActionId_doesNotOverride() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
+ SafetyCenterFlags.actionsToOverrideWithDefaultIntent =
+ mapOf(SOURCE_ID_1 to setOf("TargetActionId"))
+
+ val originalPendingIntent = pendingIntent(Intent("blah.wrong.INTENT"))
+ val dataWithoutActionToOverride =
+ sourceDataBuilder()
+ .addIssue(
+ issueBuilder()
+ .clearActions()
+ .addAction(
+ safetySourceTestData.action(
+ id = "DifferentActionId",
+ pendingIntent = originalPendingIntent
+ )
+ )
+ .build()
+ )
+ .build()
+
+ safetyCenterTestHelper.setData(SOURCE_ID_1, dataWithoutActionToOverride)
+
+ val actualPendingIntent =
+ safetyCenterManager
+ .getSafetySourceDataWithPermission(SOURCE_ID_1)!!
+ .issues[0]
+ .actions[0]
+ .pendingIntent
+ assertThat(intentsFilterEqual(actualPendingIntent, originalPendingIntent)).isTrue()
+ }
+
+ @Test
+ fun defaultActionOverride_noDefaultIntent_doesNotOverride() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceInvalidIntentConfig)
+ val targetActionId = "TargetActionId"
+ SafetyCenterFlags.actionsToOverrideWithDefaultIntent =
+ mapOf(SINGLE_SOURCE_ID to setOf(targetActionId, "AdditionalActionId"))
+
+ val originalPendingIntent = pendingIntent(Intent("blah.wrong.INTENT"))
+ val dataWithActionToOverride =
+ sourceDataBuilder()
+ .addIssue(
+ issueBuilder()
+ .clearActions()
+ .addAction(
+ safetySourceTestData.action(
+ id = targetActionId,
+ pendingIntent = originalPendingIntent
+ )
+ )
+ .build()
+ )
+ .build()
+
+ safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, dataWithActionToOverride)
+
+ val actualPendingIntent =
+ safetyCenterManager
+ .getSafetySourceDataWithPermission(SINGLE_SOURCE_ID)!!
+ .issues[0]
+ .actions[0]
+ .pendingIntent
+ assertThat(intentsFilterEqual(actualPendingIntent, originalPendingIntent)).isTrue()
+ }
+
+ private fun issueBuilder() = safetySourceTestData.defaultInformationIssueBuilder()
+
+ private fun pendingIntent(intent: Intent) =
+ PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+
+ companion object {
+ private fun sourceDataBuilder() =
+ SafetySourceData.Builder()
+ .setStatus(
+ SafetySourceStatus.Builder("OK", "Blah", SEVERITY_LEVEL_INFORMATION).build()
+ )
+
+ @RequiresApi(UPSIDE_DOWN_CAKE)
+ private fun notification(action: SafetySourceIssue.Action) =
+ SafetySourceIssue.Notification.Builder("Blah", "Bleh").addAction(action).build()
+
+ private fun intentsFilterEqual(
+ actualPendingIntent: PendingIntent,
+ expectedPendingIntent: PendingIntent?
+ ) =
+ callWithShellPermissionIdentity("android.permission.GET_INTENT_SENDER_INTENT") {
+ actualPendingIntent.intentFilterEquals(expectedPendingIntent)
+ }
+ }
+}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/NotificationCharacteristics.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/NotificationCharacteristics.kt
deleted file mode 100644
index b91c72422..000000000
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/NotificationCharacteristics.kt
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2022 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.safetycenter.functional.testing
-
-import android.app.Notification
-
-/** The characteristic properties of a notification. */
-data class NotificationCharacteristics(
- val title: String,
- val text: String,
- val actions: List<CharSequence> = emptyList(),
- val importance: Int = IMPORTANCE_ANY,
- val blockable: Boolean? = null
-) {
- companion object {
- const val IMPORTANCE_ANY = -1
-
- private fun importanceMatches(
- statusBarNotificationWithChannel: StatusBarNotificationWithChannel,
- characteristicImportance: Int
- ): Boolean {
- return characteristicImportance == IMPORTANCE_ANY ||
- statusBarNotificationWithChannel.channel.importance == characteristicImportance
- }
-
- private fun blockableMatches(
- statusBarNotificationWithChannel: StatusBarNotificationWithChannel,
- characteristicBlockable: Boolean?
- ): Boolean {
- return characteristicBlockable == null ||
- statusBarNotificationWithChannel.channel.isBlockable == characteristicBlockable
- }
-
- private fun isMatch(
- statusBarNotificationWithChannel: StatusBarNotificationWithChannel,
- characteristic: NotificationCharacteristics
- ): Boolean {
- val notif = statusBarNotificationWithChannel.statusBarNotification.notification
- return notif != null &&
- notif.extras.getString(Notification.EXTRA_TITLE) == characteristic.title &&
- notif.extras.getString(Notification.EXTRA_TEXT).orEmpty() == characteristic.text &&
- notif.actions.orEmpty().map { it.title } == characteristic.actions &&
- importanceMatches(statusBarNotificationWithChannel, characteristic.importance) &&
- blockableMatches(statusBarNotificationWithChannel, characteristic.blockable)
- }
-
- fun areMatching(
- statusBarNotifications: List<StatusBarNotificationWithChannel>,
- characteristics: List<NotificationCharacteristics>
- ): Boolean {
- if (statusBarNotifications.size != characteristics.size) {
- return false
- }
- return statusBarNotifications.zip(characteristics).all { isMatch(it.first, it.second) }
- }
- }
-}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/StatusBarNotificationWithChannel.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/StatusBarNotificationWithChannel.kt
deleted file mode 100644
index d9a998c3e..000000000
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/StatusBarNotificationWithChannel.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.safetycenter.functional.testing
-
-import android.app.NotificationChannel
-import android.service.notification.StatusBarNotification
-
-/** Tuple of [StatusBarNotification] and the [NotificationChannel] it was posted to. */
-data class StatusBarNotificationWithChannel(
- val statusBarNotification: StatusBarNotification,
- val channel: NotificationChannel
-)
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/TestNotificationListener.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/TestNotificationListener.kt
deleted file mode 100644
index 113ad3b23..000000000
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/testing/TestNotificationListener.kt
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright (C) 2022 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.safetycenter.functional.testing
-
-import android.app.NotificationChannel
-import android.content.ComponentName
-import android.os.ConditionVariable
-import android.service.notification.NotificationListenerService
-import android.service.notification.StatusBarNotification
-import android.util.Log
-import com.android.compatibility.common.util.SystemUtil
-import com.android.safetycenter.testing.Coroutines.TIMEOUT_LONG
-import com.android.safetycenter.testing.Coroutines.TIMEOUT_SHORT
-import com.android.safetycenter.testing.Coroutines.runBlockingWithTimeout
-import com.android.safetycenter.testing.Coroutines.runBlockingWithTimeoutOrNull
-import com.android.safetycenter.testing.Coroutines.waitForWithTimeout
-import com.google.common.truth.Truth.assertThat
-import java.time.Duration
-import java.util.concurrent.TimeoutException
-import kotlinx.coroutines.TimeoutCancellationException
-import kotlinx.coroutines.channels.Channel
-
-/** Used in tests to check whether expected notifications are present in the status bar. */
-class TestNotificationListener : NotificationListenerService() {
-
- private sealed class NotificationEvent(val statusBarNotification: StatusBarNotification)
-
- private class NotificationPosted(statusBarNotification: StatusBarNotification) :
- NotificationEvent(statusBarNotification) {
- override fun toString(): String = "Posted $statusBarNotification"
- }
-
- private class NotificationRemoved(statusBarNotification: StatusBarNotification) :
- NotificationEvent(statusBarNotification) {
- override fun toString(): String = "Removed $statusBarNotification"
- }
-
- override fun onNotificationPosted(statusBarNotification: StatusBarNotification) {
- super.onNotificationPosted(statusBarNotification)
- if (statusBarNotification.isSafetyCenterNotification()) {
- runBlockingWithTimeout {
- safetyCenterNotificationEvents.send(NotificationPosted(statusBarNotification))
- }
- }
- }
-
- override fun onNotificationRemoved(statusBarNotification: StatusBarNotification) {
- super.onNotificationRemoved(statusBarNotification)
- if (statusBarNotification.isSafetyCenterNotification()) {
- runBlockingWithTimeout {
- safetyCenterNotificationEvents.send(NotificationRemoved(statusBarNotification))
- }
- }
- }
-
- override fun onListenerConnected() {
- Log.d(TAG, "onListenerConnected")
- super.onListenerConnected()
- disconnected.close()
- instance = this
- connected.open()
- }
-
- override fun onListenerDisconnected() {
- Log.d(TAG, "onListenerDisconnected")
- super.onListenerDisconnected()
- connected.close()
- instance = null
- disconnected.open()
- }
-
- companion object {
- private const val TAG = "TestNotificationListene"
-
- private val id: String =
- "android.safetycenter.functional/" + TestNotificationListener::class.java.name
- private val componentName =
- ComponentName(
- "android.safetycenter.functional",
- TestNotificationListener::class.java.name
- )
-
- private val connected = ConditionVariable(false)
- private val disconnected = ConditionVariable(true)
- private var instance: TestNotificationListener? = null
-
- @Volatile
- private var safetyCenterNotificationEvents =
- Channel<NotificationEvent>(capacity = Channel.UNLIMITED)
-
- /**
- * Blocks until there are zero Safety Center notifications and there remain zero for a short
- * duration. Throws an [AssertionError] if a this condition is not met within [timeout], or
- * if it is met and then violated.
- */
- fun waitForZeroNotifications(timeout: Duration = TIMEOUT_LONG) {
- waitForNotificationCount(0, timeout)
- }
-
- /**
- * Blocks until there is exactly one Safety Center notification and ensures that remains
- * true for a short duration. Returns that notification, or throws an [AssertionError] if a
- * this condition is not met within [timeout], or if it is met and then violated.
- */
- fun waitForSingleNotification(
- timeout: Duration = TIMEOUT_LONG
- ): StatusBarNotificationWithChannel {
- return waitForNotificationCount(1, timeout).first()
- }
-
- /**
- * Blocks until there are exactly [count] Safety Center notifications and ensures that
- * remains true for a short duration. Returns those notifications, or throws an
- * [AssertionError] if a this condition is not met within [timeout], or if it is met and
- * then violated.
- */
- private fun waitForNotificationCount(
- count: Int,
- timeout: Duration = TIMEOUT_LONG
- ): List<StatusBarNotificationWithChannel> {
- return waitForNotificationsToSatisfy(timeout, description = "$count notifications") {
- it.size == count
- }
- }
-
- /**
- * Blocks until there is a single Safety Center notification, which matches the given
- * [characteristics] and ensures that remains true for a short duration. Returns that
- * notification, or throws an [AssertionError] if a this condition is not met within
- * [timeout], or if it is met and then violated.
- */
- fun waitForSingleNotificationMatching(
- characteristics: NotificationCharacteristics,
- timeout: Duration = TIMEOUT_LONG
- ): StatusBarNotificationWithChannel {
- return waitForNotificationsMatching(characteristics, timeout = timeout).first()
- }
-
- /**
- * Blocks until the Safety Center notifications match the given [characteristics] and
- * ensures that remains true for a short duration. Returns those notifications, or throws an
- * [AssertionError] if a this condition is not met within [timeout], or if it is met and
- * then violated.
- */
- fun waitForNotificationsMatching(
- vararg characteristics: NotificationCharacteristics,
- timeout: Duration = TIMEOUT_LONG
- ): List<StatusBarNotificationWithChannel> {
- val charsList = characteristics.toList()
- return waitForNotificationsToSatisfy(
- timeout,
- description = "notification(s) matching characteristics $charsList"
- ) { NotificationCharacteristics.areMatching(it, charsList) }
- }
-
- /**
- * Blocks until [forAtLeast] has elapsed, or throw an [AssertionError] if any notification
- * is posted or removed before then.
- */
- fun waitForZeroNotificationEvents(forAtLeast: Duration = TIMEOUT_SHORT) {
- val event =
- runBlockingWithTimeoutOrNull(forAtLeast) {
- safetyCenterNotificationEvents.receive()
- }
- assertThat(event).isNull()
- }
-
- private fun waitForNotificationsToSatisfy(
- timeout: Duration = TIMEOUT_LONG,
- forAtLeast: Duration = TIMEOUT_SHORT,
- description: String,
- predicate: (List<StatusBarNotificationWithChannel>) -> Boolean
- ): List<StatusBarNotificationWithChannel> {
- fun formatError(notifs: List<StatusBarNotificationWithChannel>): String {
- return "Expected: $description, but the actual notifications were: $notifs"
- }
-
- // First we wait at most timeout for the active notifications to satisfy the given
- // predicate or otherwise we throw:
- val satisfyingNotifications =
- try {
- runBlockingWithTimeout(timeout) {
- waitForNotificationsToSatisfyAsync(predicate)
- }
- } catch (e: TimeoutCancellationException) {
- throw AssertionError(formatError(getSafetyCenterNotifications()), e)
- }
-
- // Assuming the predicate was satisfied, now we ensure it is not violated for the
- // forAtLeast duration as well:
- val nonSatisfyingNotifications =
- runBlockingWithTimeoutOrNull(forAtLeast) {
- waitForNotificationsToSatisfyAsync { !predicate(it) }
- }
- if (nonSatisfyingNotifications != null) {
- // In this case the negated-predicate was satisfied before forAtLeast had elapsed
- throw AssertionError(formatError(nonSatisfyingNotifications))
- }
-
- return satisfyingNotifications
- }
-
- private suspend fun waitForNotificationsToSatisfyAsync(
- predicate: (List<StatusBarNotificationWithChannel>) -> Boolean
- ): List<StatusBarNotificationWithChannel> {
- var currentNotifications = getSafetyCenterNotifications()
- while (!predicate(currentNotifications)) {
- val event = safetyCenterNotificationEvents.receive()
- Log.d(TAG, "Received notification event: $event")
- currentNotifications = getSafetyCenterNotifications()
- }
- return currentNotifications
- }
-
- private fun getSafetyCenterNotifications(): List<StatusBarNotificationWithChannel> {
- return with(getInstanceOrThrow()) {
- val notificationsSnapshot =
- checkNotNull(getActiveNotifications()) {
- "getActiveNotifications() returned null"
- }
- val rankingSnapshot =
- checkNotNull(getCurrentRanking()) { "getCurrentRanking() returned null" }
-
- fun getChannel(key: String): NotificationChannel? {
- // This API uses a result parameter:
- val rankingOut = Ranking()
- val success = rankingSnapshot.getRanking(key, rankingOut)
- return if (success) {
- rankingOut.channel
- } else {
- null
- }
- }
-
- notificationsSnapshot
- .filter { it.isSafetyCenterNotification() }
- .mapNotNull { statusBarNotification ->
- val channel = getChannel(statusBarNotification.key)
- if (channel != null) {
- StatusBarNotificationWithChannel(statusBarNotification, channel)
- } else {
- null
- }
- }
- }
- }
-
- private fun getInstanceOrThrow(): TestNotificationListener {
- // We want to check the current values of the connected and disconnected
- // ConditionVariables, but importantly block(0) actually does not timeout immediately!
- val isConnected = connected.block(1)
- val isDisconnected = disconnected.block(1)
- check(isConnected == !isDisconnected) {
- "Notification listener condition variables are inconsistent"
- }
- check(isConnected && !isDisconnected) {
- "Notification listener was unexpectedly disconnected"
- }
- return checkNotNull(instance) { "Notification listener was unexpectedly null" }
- }
-
- /**
- * Cancels a specific notification and then waits for it to be removed by the notification
- * manager and marked as dismissed in Safety Center, or throws if it has not been removed
- * within [timeout].
- */
- fun cancelAndWait(key: String, timeout: Duration = TIMEOUT_LONG) {
- getInstanceOrThrow().cancelNotification(key)
- waitForNotificationsToSatisfy(
- timeout,
- description = "no notification with the key $key"
- ) { notifications -> notifications.none { it.statusBarNotification.key == key } }
-
- waitForIssueCacheToContainAnyDismissedNotification()
- }
-
- private fun waitForIssueCacheToContainAnyDismissedNotification() {
- // Here we wait for an issue to be recorded as dismissed according to the dumpsys
- // output. The cancelAndWait helper above first "waits" for the notification to
- // be dismissed, but this additional wait is needed to ensure the notification's delete
- // PendingIntent is handled. Without this wait there is a race condition between
- // SafetyCenterNotificationReceiver#onReceive and subsequent calls that set source data
- // and that race makes tests flaky because the dismissal status of the previous
- // notification is not well defined.
- fun dumpIssueDismissalsRepositoryState(): String =
- SystemUtil.runShellCommand("dumpsys safety_center data")
- try {
- waitForWithTimeout {
- dumpIssueDismissalsRepositoryState()
- .contains(Regex("""mNotificationDismissedAt=\d+"""))
- }
- } catch (e: TimeoutCancellationException) {
- throw IllegalStateException(
- "Notification dismissal was not recorded in the issue cache: " +
- dumpIssueDismissalsRepositoryState(),
- e
- )
- }
- }
-
- /** Runs a shell command to allow or disallow the listener. Use before and after test. */
- private fun toggleListenerAccess(allowed: Boolean) {
- // TODO(b/260335646): Try to do this using the AndroidTest.xml instead of in code
- val verb = if (allowed) "allow" else "disallow"
- SystemUtil.runShellCommand("cmd notification ${verb}_listener $id")
- if (allowed) {
- requestRebind(componentName)
- if (!connected.block(TIMEOUT_LONG.toMillis())) {
- throw TimeoutException("Notification listener did not connect in $TIMEOUT_LONG")
- }
- } else {
- if (!disconnected.block(TIMEOUT_LONG.toMillis())) {
- throw TimeoutException(
- "Notification listener did not disconnect in $TIMEOUT_LONG"
- )
- }
- }
- }
-
- /** Prepare the [TestNotificationListener] for a notification test */
- fun setup() {
- toggleListenerAccess(true)
- }
-
- /** Clean up the [TestNotificationListener] after executing a notification test. */
- fun reset() {
- waitForNotificationsToSatisfy(
- forAtLeast = Duration.ZERO,
- description = "all Safety Center notifications removed in tear down"
- ) { it.isEmpty() }
- toggleListenerAccess(false)
- safetyCenterNotificationEvents.cancel()
- safetyCenterNotificationEvents = Channel(capacity = Channel.UNLIMITED)
- }
-
- private fun StatusBarNotification.isSafetyCenterNotification(): Boolean =
- packageName == "android" && notification.channelId.startsWith("safety_center")
- }
-}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/PrivacySubpageTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/PrivacySubpageTest.kt
deleted file mode 100644
index 0c90029e0..000000000
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/PrivacySubpageTest.kt
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.safetycenter.functional.ui
-
-import android.content.Context
-import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE
-import android.os.Bundle
-import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID
-import android.safetycenter.config.SafetySource
-import androidx.test.core.app.ApplicationProvider.getApplicationContext
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SdkSuppress
-import androidx.test.uiautomator.By
-import com.android.compatibility.common.util.DisableAnimationRule
-import com.android.compatibility.common.util.FreezeRotationRule
-import com.android.compatibility.common.util.UiAutomatorUtils2
-import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterActivity
-import com.android.safetycenter.testing.SafetyCenterActivityLauncher.openPageAndExit
-import com.android.safetycenter.testing.SafetyCenterFlags
-import com.android.safetycenter.testing.SafetyCenterFlags.deviceSupportsSafetyCenter
-import com.android.safetycenter.testing.SafetyCenterTestConfigs
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.PRIVACY_SOURCE_ID_1
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_1
-import com.android.safetycenter.testing.SafetyCenterTestHelper
-import com.android.safetycenter.testing.SafetySourceTestData
-import com.android.safetycenter.testing.UiTestHelper.MORE_ISSUES_LABEL
-import com.android.safetycenter.testing.UiTestHelper.clickMoreIssuesCard
-import com.android.safetycenter.testing.UiTestHelper.resetRotation
-import com.android.safetycenter.testing.UiTestHelper.waitAllTextDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitButtonDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitPageTitleDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitSourceIssueDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitSourceIssueNotDisplayed
-import org.junit.After
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/** Functional tests for the Privacy subpage in Safety Center. */
-@RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
-class PrivacySubpageTest {
-
- @get:Rule val disableAnimationRule = DisableAnimationRule()
-
- @get:Rule val freezeRotationRule = FreezeRotationRule()
-
- private val context: Context = getApplicationContext()
- private val safetyCenterTestHelper = SafetyCenterTestHelper(context)
- private val safetySourceTestData = SafetySourceTestData(context)
- private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
-
- // JUnit's Assume is not supported in @BeforeClass by the tests runner, so this is used to
- // manually skip the setup and teardown methods.
- private val shouldRunTests = context.deviceSupportsSafetyCenter()
-
- @Before
- fun assumeDeviceSupportsSafetyCenterToRunTests() {
- assumeTrue(shouldRunTests)
- }
-
- @Before
- fun enableSafetyCenterBeforeTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.setup()
- SafetyCenterFlags.showSubpages = true
- }
-
- @After
- fun clearDataAfterTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.reset()
- UiAutomatorUtils2.getUiDevice().resetRotation()
- }
-
- @Test
- fun privacySubpage_openWithIntentExtra_showsSubpageData() {
- val config = safetyCenterTestConfigs.privacySubpageConfig
- safetyCenterTestHelper.setConfig(config)
- val sourcesGroup = config.safetySourcesGroups.first()
- val firstSource: SafetySource = sourcesGroup.safetySources.first()
- val lastSource: SafetySource = sourcesGroup.safetySources.last()
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, sourcesGroup.id)
-
- context.launchSafetyCenterActivity(extras) {
- waitAllTextDisplayed(
- context.getString(firstSource.titleResId),
- context.getString(firstSource.summaryResId),
- "Controls",
- context.getString(lastSource.titleResId),
- context.getString(lastSource.summaryResId)
- )
- }
- }
-
- @Test
- fun privacySubpage_clickingOnEntry_redirectsToDifferentScreen() {
- val config = safetyCenterTestConfigs.privacySubpageConfig
- safetyCenterTestHelper.setConfig(config)
- val sourcesGroup = config.safetySourcesGroups.first()
- val source: SafetySource = sourcesGroup.safetySources.first()
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, sourcesGroup.id)
-
- context.launchSafetyCenterActivity(extras) {
- waitDisplayed(By.text(context.getString(source.titleResId))) { it.click() }
- waitButtonDisplayed("Exit test activity") { it.click() }
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
- }
- }
-
- @Test
- fun privacySubpage_withMultipleIssues_displaysExpectedWarningCards() {
- val config = safetyCenterTestConfigs.privacySubpageConfig
- safetyCenterTestHelper.setConfig(config)
- val firstSourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- val secondSourceData = safetySourceTestData.informationWithIssueWithAttributionTitle
- safetyCenterTestHelper.setData(PRIVACY_SOURCE_ID_1, firstSourceData)
- safetyCenterTestHelper.setData(SOURCE_ID_1, secondSourceData)
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, config.safetySourcesGroups.first().id)
-
- context.launchSafetyCenterActivity(extras) {
- waitSourceIssueDisplayed(firstSourceData.issues[0])
- waitAllTextDisplayed(MORE_ISSUES_LABEL)
- waitSourceIssueNotDisplayed(secondSourceData.issues[0])
-
- clickMoreIssuesCard()
-
- waitSourceIssueDisplayed(firstSourceData.issues[0])
- waitAllTextDisplayed(MORE_ISSUES_LABEL)
- waitSourceIssueDisplayed(secondSourceData.issues[0])
- }
- }
-
- @Test
- fun privacySubpage_openWithIntentExtra_showsPrivacyControls() {
- val config = safetyCenterTestConfigs.privacySubpageConfig
- safetyCenterTestHelper.setConfig(config)
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, config.safetySourcesGroups.first().id)
-
- context.launchSafetyCenterActivity(extras) {
- waitAllTextDisplayed(
- "Camera access",
- "Microphone access",
- "Show clipboard access",
- "Show passwords",
- "Location access"
- )
- }
- }
-
- @Test
- fun privacySubpage_clickingOnLocationEntry_redirectsToLocationScreen() {
- val config = safetyCenterTestConfigs.privacySubpageConfig
- safetyCenterTestHelper.setConfig(config)
- val sourcesGroup = config.safetySourcesGroups.first()
- val source: SafetySource = sourcesGroup.safetySources.first()
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, sourcesGroup.id)
-
- context.launchSafetyCenterActivity(extras) {
- openPageAndExit("Location access") {
- waitPageTitleDisplayed("Location")
- waitAllTextDisplayed("Use location")
- }
-
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
- }
- }
-
- @Test
- fun settingsSearch_openWithPrivacyIntentExtra_showsPrivacySubpage() {
- val config = safetyCenterTestConfigs.privacySubpageConfig
- val sourcesGroup = config.safetySourcesGroups.first()
- val source: SafetySource = sourcesGroup.safetySources.first()
- safetyCenterTestHelper.setConfig(config)
- val extras = Bundle()
- extras.putString(EXTRA_SETTINGS_FRAGMENT_ARGS_KEY, "privacy_camera_toggle")
-
- context.launchSafetyCenterActivity(extras) {
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId),
- "Controls",
- )
- }
- }
-
- companion object {
- private const val EXTRA_SETTINGS_FRAGMENT_ARGS_KEY = ":settings:fragment_args_key"
- }
-}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterQsActivityTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterQsActivityTest.kt
index 9c4d720d3..73d6a0737 100644
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterQsActivityTest.kt
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterQsActivityTest.kt
@@ -16,29 +16,23 @@
package android.safetycenter.functional.ui
-import android.Manifest.permission.MANAGE_SENSOR_PRIVACY
-import android.Manifest.permission.OBSERVE_SENSOR_PRIVACY
import android.content.Context
-import android.hardware.SensorPrivacyManager
import android.hardware.SensorPrivacyManager.Sensors.CAMERA
import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
-import android.hardware.SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE
-import android.platform.test.rule.ScreenRecordRule
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import com.android.compatibility.common.util.DisableAnimationRule
import com.android.compatibility.common.util.FreezeRotationRule
+import com.android.safetycenter.testing.EnableSensorRule
import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterQsActivity
-import com.android.safetycenter.testing.SafetyCenterFlags.deviceSupportsSafetyCenter
import com.android.safetycenter.testing.SafetyCenterTestConfigs
import com.android.safetycenter.testing.SafetyCenterTestHelper
-import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
+import com.android.safetycenter.testing.SafetyCenterTestRule
+import com.android.safetycenter.testing.SupportsSafetyCenterRule
import com.android.safetycenter.testing.UiTestHelper.waitAllTextDisplayed
import com.android.safetycenter.testing.UiTestHelper.waitDisplayed
import com.android.safetycenter.testing.UiTestHelper.waitPageTitleDisplayed
-import org.junit.After
-import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -48,66 +42,22 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SafetyCenterQsActivityTest {
- @get:Rule val disableAnimationRule = DisableAnimationRule()
-
- @get:Rule val freezeRotationRule = FreezeRotationRule()
-
- @get:Rule val screenRecordRule = ScreenRecordRule()
-
private val context: Context = getApplicationContext()
private val safetyCenterTestHelper = SafetyCenterTestHelper(context)
private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
- private val sensorPrivacyManager = context.getSystemService(SensorPrivacyManager::class.java)!!
- private var shouldRunTests =
- context.deviceSupportsSafetyCenter() &&
- deviceSupportsSensorToggle(CAMERA) &&
- deviceSupportsSensorToggle(MICROPHONE)
- private var oldCameraState: Boolean = false
- private var oldMicrophoneState: Boolean = false
- @Before
- fun assumeDeviceSupportsSafetyCenterToRunTests() {
- assumeTrue(shouldRunTests)
- }
+ @get:Rule(order = 1) val supportsSafetyCenterRule = SupportsSafetyCenterRule(context)
+ @get:Rule(order = 2) val enableCameraRule = EnableSensorRule(context, CAMERA)
+ @get:Rule(order = 3) val enableMicrophoneRule = EnableSensorRule(context, MICROPHONE)
+ @get:Rule(order = 4) val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper)
+ @get:Rule(order = 5) val disableAnimationRule = DisableAnimationRule()
+ @get:Rule(order = 6) val freezeRotationRule = FreezeRotationRule()
@Before
- fun enableSafetyCenterBeforeTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.setup()
+ fun setTestConfigBeforeTest() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
}
- @After
- fun clearDataAfterTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.reset()
- }
-
- @Before
- fun enablePrivacyControlsBeforeTest() {
- if (!shouldRunTests) {
- return
- }
- oldCameraState = isSensorEnabled(CAMERA)
- setSensorState(CAMERA, true)
-
- oldMicrophoneState = isSensorEnabled(MICROPHONE)
- setSensorState(MICROPHONE, true)
- }
-
- @After
- fun restorePrivacyControlsAfterTest() {
- if (!shouldRunTests) {
- return
- }
- setSensorState(CAMERA, oldCameraState)
- setSensorState(MICROPHONE, oldMicrophoneState)
- }
-
@Test
fun launchActivity_fromQuickSettings_hasContentDescriptions() {
context.launchSafetyCenterQsActivity {
@@ -122,7 +72,6 @@ class SafetyCenterQsActivityTest {
}
@Test
- @ScreenRecordRule.ScreenRecord
fun launchActivity_togglePrivacyControls_hasUpdatedDescriptions() {
context.launchSafetyCenterQsActivity {
// Toggle privacy controls
@@ -134,25 +83,4 @@ class SafetyCenterQsActivityTest {
waitDisplayed(By.desc("Switch. Mic access. Blocked"))
}
}
-
- private fun deviceSupportsSensorToggle(sensor: Int): Boolean {
- return sensorPrivacyManager.supportsSensorToggle(sensor) &&
- sensorPrivacyManager.supportsSensorToggle(TOGGLE_TYPE_SOFTWARE, sensor)
- }
-
- private fun isSensorEnabled(sensor: Int): Boolean {
- val isSensorDisabled =
- callWithShellPermissionIdentity(OBSERVE_SENSOR_PRIVACY) {
- sensorPrivacyManager.isSensorPrivacyEnabled(TOGGLE_TYPE_SOFTWARE, sensor)
- }
- return !isSensorDisabled
- }
-
- private fun setSensorState(sensor: Int, enabled: Boolean) {
- val disableSensor = !enabled
- // The sensor is enabled iff the privacy control is disabled.
- callWithShellPermissionIdentity(MANAGE_SENSOR_PRIVACY, OBSERVE_SENSOR_PRIVACY) {
- sensorPrivacyManager.setSensorPrivacy(sensor, disableSensor)
- }
- }
}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterStatusCardTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterStatusCardTest.kt
index f4ed328ae..f76a52256 100644
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterStatusCardTest.kt
+++ b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterStatusCardTest.kt
@@ -17,31 +17,31 @@
package android.safetycenter.functional.ui
import android.content.Context
+import android.os.Build
+import android.safetycenter.SafetySourceData
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import com.android.compatibility.common.util.DisableAnimationRule
import com.android.compatibility.common.util.FreezeRotationRule
-import com.android.safetycenter.resources.SafetyCenterResourcesContext
+import com.android.safetycenter.resources.SafetyCenterResourcesApk
import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterActivity
-import com.android.safetycenter.testing.SafetyCenterFlags.deviceSupportsSafetyCenter
import com.android.safetycenter.testing.SafetyCenterTestConfigs
import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID
import com.android.safetycenter.testing.SafetyCenterTestData
import com.android.safetycenter.testing.SafetyCenterTestHelper
+import com.android.safetycenter.testing.SafetyCenterTestRule
import com.android.safetycenter.testing.SafetySourceIntentHandler.Request
import com.android.safetycenter.testing.SafetySourceIntentHandler.Response
import com.android.safetycenter.testing.SafetySourceReceiver
import com.android.safetycenter.testing.SafetySourceTestData
+import com.android.safetycenter.testing.SupportsSafetyCenterRule
import com.android.safetycenter.testing.UiTestHelper.RESCAN_BUTTON_LABEL
import com.android.safetycenter.testing.UiTestHelper.waitAllTextDisplayed
import com.android.safetycenter.testing.UiTestHelper.waitButtonDisplayed
import com.android.safetycenter.testing.UiTestHelper.waitButtonNotDisplayed
import com.android.safetycenter.testing.UiTestHelper.waitDisplayed
import com.android.safetycenter.testing.UiTestHelper.waitNotDisplayed
-import org.junit.After
-import org.junit.Assume.assumeTrue
-import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -50,42 +50,17 @@ import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class SafetyCenterStatusCardTest {
- @get:Rule val disableAnimationRule = DisableAnimationRule()
-
- @get:Rule val freezeRotationRule = FreezeRotationRule()
-
private val context: Context = getApplicationContext()
-
- private val safetyCenterResourcesContext = SafetyCenterResourcesContext.forTests(context)
+ private val safetyCenterResourcesApk = SafetyCenterResourcesApk.forTests(context)
private val safetyCenterTestHelper = SafetyCenterTestHelper(context)
private val safetySourceTestData = SafetySourceTestData(context)
private val safetyCenterTestData = SafetyCenterTestData(context)
private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
- // JUnit's Assume is not supported in @BeforeClass by the tests runner, so this is used to
- // manually skip the setup and teardown methods.
- private val shouldRunTests = context.deviceSupportsSafetyCenter()
-
- @Before
- fun assumeDeviceSupportsSafetyCenterToRunTests() {
- assumeTrue(shouldRunTests)
- }
-
- @Before
- fun enableSafetyCenterBeforeTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.setup()
- }
-
- @After
- fun clearDataAfterTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.reset()
- }
+ @get:Rule(order = 1) val supportsSafetyCenterRule = SupportsSafetyCenterRule(context)
+ @get:Rule(order = 2) val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper)
+ @get:Rule(order = 3) val disableAnimationRule = DisableAnimationRule()
+ @get:Rule(order = 4) val freezeRotationRule = FreezeRotationRule()
@Test
fun withUnknownStatus_displaysScanningOnLoad() {
@@ -93,8 +68,8 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName("scanning_title"),
- safetyCenterResourcesContext.getStringByName("loading_summary")
+ safetyCenterResourcesApk.getStringByName("scanning_title"),
+ safetyCenterResourcesApk.getStringByName("loading_summary")
)
}
}
@@ -109,8 +84,8 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_title"),
- safetyCenterResourcesContext.getStringByName("loading_summary")
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_title"),
+ safetyCenterResourcesApk.getStringByName("loading_summary")
)
}
}
@@ -122,12 +97,8 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity(withReceiverPermission = true) {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_ok_review_title"
- ),
- safetyCenterResourcesContext.getStringByName(
- "overall_severity_level_ok_review_summary"
- )
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_review_title"),
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_review_summary")
)
waitButtonDisplayed(RESCAN_BUTTON_LABEL)
}
@@ -136,6 +107,7 @@ class SafetyCenterStatusCardTest {
@Test
fun withInformationAndNoIssues_hasRescanButton() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ preSetDataOnT(SINGLE_SOURCE_ID, safetySourceTestData.information)
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.information)
@@ -143,8 +115,8 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity(withReceiverPermission = true) {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_title"),
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_summary")
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_title"),
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_summary")
)
waitButtonDisplayed(RESCAN_BUTTON_LABEL)
}
@@ -153,6 +125,7 @@ class SafetyCenterStatusCardTest {
@Test
fun withInformationAndNoIssues_hasContentDescriptions() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ preSetDataOnT(SINGLE_SOURCE_ID, safetySourceTestData.information)
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.information)
@@ -167,6 +140,7 @@ class SafetyCenterStatusCardTest {
@Test
fun withInformationIssue_doesNotHaveRescanButton() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ preSetDataOnT(SINGLE_SOURCE_ID, safetySourceTestData.informationWithIssue)
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.informationWithIssue)
@@ -174,7 +148,7 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity(withReceiverPermission = true) {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_title"),
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_title"),
safetyCenterTestData.getAlertString(1)
)
waitButtonNotDisplayed(RESCAN_BUTTON_LABEL)
@@ -184,6 +158,10 @@ class SafetyCenterStatusCardTest {
@Test
fun withRecommendationIssue_doesNotHaveRescanButton() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ safetyCenterTestHelper.setData(
+ SINGLE_SOURCE_ID,
+ safetySourceTestData.recommendationWithGeneralIssue
+ )
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.recommendationWithGeneralIssue)
@@ -191,7 +169,7 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity(withReceiverPermission = true) {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName(
+ safetyCenterResourcesApk.getStringByName(
"overall_severity_level_safety_recommendation_title"
),
safetyCenterTestData.getAlertString(1)
@@ -203,6 +181,10 @@ class SafetyCenterStatusCardTest {
@Test
fun withCriticalWarningIssue_doesNotHaveRescanButton() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ safetyCenterTestHelper.setData(
+ SINGLE_SOURCE_ID,
+ safetySourceTestData.criticalWithResolvingGeneralIssue
+ )
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.criticalWithResolvingGeneralIssue)
@@ -210,7 +192,7 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity(withReceiverPermission = true) {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName(
+ safetyCenterResourcesApk.getStringByName(
"overall_severity_level_critical_safety_warning_title"
),
safetyCenterTestData.getAlertString(1)
@@ -222,6 +204,7 @@ class SafetyCenterStatusCardTest {
@Test
fun withKnownStatus_displaysScanningOnRescan() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ preSetDataOnT(SINGLE_SOURCE_ID, safetySourceTestData.information)
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.information)
@@ -229,15 +212,15 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity(withReceiverPermission = true) {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_title"),
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_summary")
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_title"),
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_summary")
)
waitButtonDisplayed(RESCAN_BUTTON_LABEL) { it.click() }
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName("scanning_title"),
- safetyCenterResourcesContext.getStringByName("loading_summary")
+ safetyCenterResourcesApk.getStringByName("scanning_title"),
+ safetyCenterResourcesApk.getStringByName("loading_summary")
)
}
}
@@ -245,6 +228,7 @@ class SafetyCenterStatusCardTest {
@Test
fun rescan_updatesDataAfterScanCompletes() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
+ preSetDataOnT(SINGLE_SOURCE_ID, safetySourceTestData.information)
SafetySourceReceiver.setResponse(
Request.Refresh(SINGLE_SOURCE_ID),
Response.SetData(safetySourceTestData.information)
@@ -256,18 +240,28 @@ class SafetyCenterStatusCardTest {
context.launchSafetyCenterActivity(withReceiverPermission = true) {
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_title"),
- safetyCenterResourcesContext.getStringByName("overall_severity_level_ok_summary")
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_title"),
+ safetyCenterResourcesApk.getStringByName("overall_severity_level_ok_summary")
)
waitButtonDisplayed(RESCAN_BUTTON_LABEL) { it.click() }
waitAllTextDisplayed(
- safetyCenterResourcesContext.getStringByName(
+ safetyCenterResourcesApk.getStringByName(
"overall_severity_level_safety_recommendation_title"
),
safetyCenterTestData.getAlertString(1)
)
}
}
+
+ /**
+ * Sets the given data for the given source ID if this test is running on T builds. This is a
+ * mitigation for b/301234118 which seems to only fail consistently on T.
+ */
+ private fun preSetDataOnT(sourceId: String, safetySourceData: SafetySourceData) {
+ if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.TIRAMISU) {
+ safetyCenterTestHelper.setData(sourceId, safetySourceData)
+ }
+ }
}
diff --git a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterSubpagesTest.kt b/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterSubpagesTest.kt
deleted file mode 100644
index eeb512037..000000000
--- a/tests/functional/safetycenter/singleuser/src/android/safetycenter/functional/ui/SafetyCenterSubpagesTest.kt
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- * Copyright (C) 2022 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.safetycenter.functional.ui
-
-import android.content.Context
-import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE
-import android.os.Bundle
-import android.safetycenter.SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID
-import android.safetycenter.SafetySourceData
-import android.safetycenter.SafetySourceIssue
-import android.safetycenter.config.SafetySource
-import android.safetycenter.config.SafetySourcesGroup
-import androidx.test.core.app.ApplicationProvider.getApplicationContext
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SdkSuppress
-import androidx.test.platform.app.InstrumentationRegistry
-import androidx.test.uiautomator.By
-import com.android.compatibility.common.util.DisableAnimationRule
-import com.android.compatibility.common.util.FreezeRotationRule
-import com.android.compatibility.common.util.RetryRule
-import com.android.compatibility.common.util.UiAutomatorUtils2
-import com.android.safetycenter.resources.SafetyCenterResourcesContext
-import com.android.safetycenter.testing.Coroutines.TIMEOUT_LONG
-import com.android.safetycenter.testing.Coroutines.TIMEOUT_SHORT
-import com.android.safetycenter.testing.SafetyCenterActivityLauncher.launchSafetyCenterActivity
-import com.android.safetycenter.testing.SafetyCenterActivityLauncher.openPageAndExit
-import com.android.safetycenter.testing.SafetyCenterActivityLauncher.openPageAndExitAllowingRetries
-import com.android.safetycenter.testing.SafetyCenterFlags
-import com.android.safetycenter.testing.SafetyCenterFlags.deviceSupportsSafetyCenter
-import com.android.safetycenter.testing.SafetyCenterTestConfigs
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.MULTIPLE_SOURCES_GROUP_ID_1
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SINGLE_SOURCE_ID
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_1
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_2
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_3
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_4
-import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_5
-import com.android.safetycenter.testing.SafetyCenterTestData
-import com.android.safetycenter.testing.SafetyCenterTestHelper
-import com.android.safetycenter.testing.SafetySourceIntentHandler.Request
-import com.android.safetycenter.testing.SafetySourceIntentHandler.Response
-import com.android.safetycenter.testing.SafetySourceReceiver
-import com.android.safetycenter.testing.SafetySourceTestData
-import com.android.safetycenter.testing.UiTestHelper.MORE_ISSUES_LABEL
-import com.android.safetycenter.testing.UiTestHelper.clickConfirmDismissal
-import com.android.safetycenter.testing.UiTestHelper.clickDismissIssueCard
-import com.android.safetycenter.testing.UiTestHelper.clickMoreIssuesCard
-import com.android.safetycenter.testing.UiTestHelper.clickOpenSubpage
-import com.android.safetycenter.testing.UiTestHelper.clickSubpageBrandChip
-import com.android.safetycenter.testing.UiTestHelper.resetRotation
-import com.android.safetycenter.testing.UiTestHelper.rotate
-import com.android.safetycenter.testing.UiTestHelper.setAnimationsEnabled
-import com.android.safetycenter.testing.UiTestHelper.waitAllTextDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitAllTextNotDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitButtonDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitCollapsedIssuesDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitExpandedIssuesDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitGroupShownOnHomepage
-import com.android.safetycenter.testing.UiTestHelper.waitPageTitleDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitPageTitleNotDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitSourceIssueDisplayed
-import com.android.safetycenter.testing.UiTestHelper.waitSourceIssueNotDisplayed
-import java.util.concurrent.TimeUnit
-import org.junit.After
-import org.junit.Assume.assumeTrue
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-import org.junit.rules.Timeout
-import org.junit.runner.RunWith
-
-/** Functional tests for generic subpages in Safety Center. */
-@RunWith(AndroidJUnit4::class)
-@SdkSuppress(minSdkVersion = UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
-class SafetyCenterSubpagesTest {
-
- @get:Rule val disableAnimationRule = DisableAnimationRule()
-
- @get:Rule val freezeRotationRule = FreezeRotationRule()
-
- // It is necessery to couple RetryRule and Timeout to ensure that all the retries together are
- // restricted with the test timeout
- @get:Rule val retryRule = RetryRule(/* retries= */ 3)
- @get:Rule
- val timeoutRule =
- Timeout(
- InstrumentationRegistry.getArguments().getString("timeout_msec", "60000").toLong(),
- TimeUnit.MILLISECONDS
- )
-
- private val context: Context = getApplicationContext()
- private val safetyCenterTestHelper = SafetyCenterTestHelper(context)
- private val safetySourceTestData = SafetySourceTestData(context)
- private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
- private val safetyCenterResourcesContext = SafetyCenterResourcesContext.forTests(context)
-
- // JUnit's Assume is not supported in @BeforeClass by the tests runner, so this is used to
- // manually skip the setup and teardown methods.
- private val shouldRunTests = context.deviceSupportsSafetyCenter()
-
- @Before
- fun assumeDeviceSupportsSafetyCenterToRunTests() {
- assumeTrue(shouldRunTests)
- }
-
- @Before
- fun enableSafetyCenterBeforeTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.setup()
- SafetyCenterFlags.showSubpages = true
- }
-
- @After
- fun clearDataAfterTest() {
- if (!shouldRunTests) {
- return
- }
- safetyCenterTestHelper.reset()
- UiAutomatorUtils2.getUiDevice().resetRotation()
- }
-
- @Test
- fun launchSafetyCenter_withSubpagesIntentExtra_showsSubpageTitle() {
- val config = safetyCenterTestConfigs.multipleSourceGroupsConfig
- val sourceGroup = config.safetySourcesGroups.first()!!
- safetyCenterTestHelper.setConfig(config)
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, MULTIPLE_SOURCES_GROUP_ID_1)
-
- context.launchSafetyCenterActivity(extras) {
- waitPageTitleDisplayed(context.getString(sourceGroup.titleResId))
- }
- }
-
- @Test
- fun launchSafetyCenter_withSubpagesIntentExtraButFlagDisabled_showsHomepageTitle() {
- SafetyCenterFlags.showSubpages = false
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourceGroupsConfig)
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, MULTIPLE_SOURCES_GROUP_ID_1)
-
- context.launchSafetyCenterActivity(extras) { waitPageTitleDisplayed("Security & privacy") }
- }
-
- @Test
- fun launchSafetyCenter_withNonExistingGroupID_opensHomepageAsFallback() {
- val config = safetyCenterTestConfigs.multipleSourceGroupsConfig
- val sourceGroup = config.safetySourcesGroups.first()!!
- safetyCenterTestHelper.setConfig(config)
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, "non_existing_group_id")
-
- context.launchSafetyCenterActivity(extras) {
- waitPageTitleNotDisplayed(context.getString(sourceGroup.titleResId))
- waitPageTitleDisplayed("Security & privacy")
- }
- }
-
- @Test
- fun launchSafetyCenter_withMultipleGroups_showsHomepageEntries() {
- val sourceTestData = safetySourceTestData.information
- with(safetyCenterTestHelper) {
- setConfig(safetyCenterTestConfigs.multipleSourceGroupsConfig)
- setData(SOURCE_ID_1, sourceTestData)
- setData(SOURCE_ID_2, sourceTestData)
- setData(SOURCE_ID_3, sourceTestData)
- setData(SOURCE_ID_4, sourceTestData)
- setData(SOURCE_ID_5, sourceTestData)
- }
- val firstGroup =
- safetyCenterTestConfigs.multipleSourceGroupsConfig.safetySourcesGroups.first()
- val lastGroup =
- safetyCenterTestConfigs.multipleSourceGroupsConfig.safetySourcesGroups.last()
-
- context.launchSafetyCenterActivity {
- waitAllTextDisplayed(
- context.getString(firstGroup.titleResId),
- context.getString(firstGroup.summaryResId),
- context.getString(lastGroup.titleResId),
- context.getString(lastGroup.summaryResId)
- )
-
- openPageAndExit(context.getString(lastGroup.titleResId)) {
- waitPageTitleDisplayed(context.getString(lastGroup.titleResId))
- waitAllTextNotDisplayed(context.getString(lastGroup.summaryResId))
- }
- }
- }
-
- @Test
- fun launchSafetyCenter_withMultipleGroupsButFlagDisabled_showsExpandAndCollapseEntries() {
- SafetyCenterFlags.showSubpages = false
- val sourceTestData = safetySourceTestData.information
- with(safetyCenterTestHelper) {
- setConfig(safetyCenterTestConfigs.multipleSourceGroupsConfig)
- setData(SOURCE_ID_1, sourceTestData)
- setData(SOURCE_ID_2, sourceTestData)
- setData(SOURCE_ID_3, sourceTestData)
- setData(SOURCE_ID_4, sourceTestData)
- setData(SOURCE_ID_5, sourceTestData)
- }
- val firstGroup =
- safetyCenterTestConfigs.multipleSourceGroupsConfig.safetySourcesGroups.first()
- val lastGroup =
- safetyCenterTestConfigs.multipleSourceGroupsConfig.safetySourcesGroups.last()
-
- context.launchSafetyCenterActivity {
- waitAllTextDisplayed(
- context.getString(firstGroup.titleResId),
- context.getString(firstGroup.summaryResId),
- context.getString(lastGroup.titleResId)
- )
- waitDisplayed(By.text(context.getString(lastGroup.summaryResId))) { it.click() }
-
- // Verifying that the group is expanded and sources are displayed
- waitAllTextDisplayed(sourceTestData.status!!.title, sourceTestData.status!!.summary)
- waitAllTextNotDisplayed(context.getString(lastGroup.summaryResId))
- }
- }
-
- @Test
- fun launchSafetyCenter_redirectBackFromSubpage_showsHomepageEntries() {
- with(safetyCenterTestHelper) {
- setConfig(safetyCenterTestConfigs.multipleSourceGroupsConfig)
- setData(SOURCE_ID_1, safetySourceTestData.information)
- setData(SOURCE_ID_2, safetySourceTestData.information)
- }
- val firstGroup =
- safetyCenterTestConfigs.multipleSourceGroupsConfig.safetySourcesGroups.first()
-
- context.launchSafetyCenterActivity {
- waitGroupShownOnHomepage(context, firstGroup)
-
- openPageAndExit(context.getString(firstGroup.titleResId)) {
- waitPageTitleDisplayed(context.getString(firstGroup.titleResId))
- waitAllTextNotDisplayed(context.getString(firstGroup.summaryResId))
- }
-
- waitGroupShownOnHomepage(context, firstGroup)
- }
- }
-
- @Test
- fun entryListWithMultipleSources_clickingOnHomepageEntry_showsSubpageEntries() {
- with(safetyCenterTestHelper) {
- setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
- setData(
- SOURCE_ID_1,
- safetySourceTestData.buildSafetySourceDataWithSummary(
- severityLevel = SafetySourceData.SEVERITY_LEVEL_INFORMATION,
- entryTitle = SAFETY_SOURCE_1_TITLE,
- entrySummary = SAFETY_SOURCE_1_SUMMARY
- )
- )
- setData(
- SOURCE_ID_2,
- safetySourceTestData.buildSafetySourceDataWithSummary(
- severityLevel = SafetySourceData.SEVERITY_LEVEL_INFORMATION,
- entryTitle = SAFETY_SOURCE_2_TITLE,
- entrySummary = SAFETY_SOURCE_2_SUMMARY
- )
- )
- setData(
- SOURCE_ID_3,
- safetySourceTestData.buildSafetySourceDataWithSummary(
- severityLevel = SafetySourceData.SEVERITY_LEVEL_INFORMATION,
- entryTitle = SAFETY_SOURCE_3_TITLE,
- entrySummary = SAFETY_SOURCE_3_SUMMARY
- )
- )
- }
- val firstGroup = safetyCenterTestConfigs.multipleSourcesConfig.safetySourcesGroups[0]
- val secondGroup = safetyCenterTestConfigs.multipleSourcesConfig.safetySourcesGroups[1]
-
- context.launchSafetyCenterActivity {
- // Verifying that subpage entries of the first group are displayed
- openPageAndExit(context.getString(firstGroup.titleResId)) {
- waitAllTextNotDisplayed(context.getString(firstGroup.summaryResId))
- waitAllTextDisplayed(
- SAFETY_SOURCE_1_TITLE,
- SAFETY_SOURCE_1_SUMMARY,
- SAFETY_SOURCE_2_TITLE,
- SAFETY_SOURCE_2_SUMMARY
- )
- }
-
- // Verifying that subpage entries of the second group are displayed
- openPageAndExit(context.getString(secondGroup.titleResId)) {
- waitAllTextNotDisplayed(context.getString(secondGroup.summaryResId))
- waitAllTextDisplayed(SAFETY_SOURCE_3_TITLE, SAFETY_SOURCE_3_SUMMARY)
- }
- }
- }
-
- @Test
- fun entryListWithSingleSource_clickingOnSubpageEntry_redirectsToDifferentScreen() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val source: SafetySource = sourcesGroup.safetySources.first()
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitDisplayed(By.text(context.getString(source.titleResId))) { it.click() }
- waitButtonDisplayed("Exit test activity") { it.click() }
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
- }
- }
- }
-
- @Test
- fun entryListWithSingleSource_clickingTheInfoIcon_redirectsToDifferentScreen() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- val sourceTestData = safetySourceTestData.informationWithIconAction
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceTestData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitDisplayed(By.desc("Information")) { it.click() }
- waitButtonDisplayed("Exit test activity") { it.click() }
- waitAllTextDisplayed(sourceTestData.status!!.title, sourceTestData.status!!.summary)
- }
- }
- }
-
- @Test
- fun entryListWithSingleSource_clickingTheGearIcon_redirectsToDifferentScreen() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- val sourceTestData = safetySourceTestData.informationWithGearIconAction
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceTestData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitDisplayed(By.desc("Settings")) { it.click() }
- waitButtonDisplayed("Exit test activity") { it.click() }
- waitAllTextDisplayed(sourceTestData.status!!.title, sourceTestData.status!!.summary)
- }
- }
- }
-
- @Test
- fun entryListWithSingleSource_clickingAnUnclickableDisabledEntry_doesNothing() {
- val config = safetyCenterTestConfigs.singleSourceInvalidIntentConfig
- safetyCenterTestHelper.setConfig(config)
- val sourceTestData = safetySourceTestData.informationWithNullIntent
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceTestData)
- val sourcesGroup = config.safetySourcesGroups.first()
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitDisplayed(By.text(sourceTestData.status!!.title.toString())) { it.click() }
-
- // Verifying that clicking on the entry doesn't redirect to any other screen
- waitAllTextDisplayed(sourceTestData.status!!.title, sourceTestData.status!!.summary)
- }
- }
- }
-
- @Test
- fun entryListWithSingleSource_clickingAClickableDisabledEntry_redirectsToDifferentScreen() {
- val config = safetyCenterTestConfigs.singleSourceConfig
- safetyCenterTestHelper.setConfig(config)
- val sourceTestData = safetySourceTestData.unspecifiedDisabledWithTestActivityRedirect
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceTestData)
- val sourcesGroup = config.safetySourcesGroups.first()
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitDisplayed(By.text(sourceTestData.status!!.title.toString())) { it.click() }
-
- waitButtonDisplayed("Exit test activity") { it.click() }
- }
- }
- }
-
- @Test
- fun entryListWithSingleSource_updateSafetySourceData_displayedDataIsUpdated() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val source: SafetySource = sourcesGroup.safetySources.first()
-
- context.launchSafetyCenterActivity(withReceiverPermission = true) {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
- }
-
- SafetySourceReceiver.setResponse(
- Request.Refresh(SINGLE_SOURCE_ID),
- Response.SetData(
- safetySourceTestData.buildSafetySourceDataWithSummary(
- severityLevel = SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION,
- entryTitle = "Updated title",
- entrySummary = "Updated summary"
- )
- )
- )
-
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitAllTextNotDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
- waitAllTextDisplayed("Updated title", "Updated summary")
- }
- }
- }
-
- @Test
- fun entryListWithSingleSource_updateSafetySourceDataAndRotate_displayedDataIsNotUpdated() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val source: SafetySource = sourcesGroup.safetySources.first()
-
- context.launchSafetyCenterActivity(withReceiverPermission = true) {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
-
- SafetySourceReceiver.setResponse(
- Request.Refresh(SINGLE_SOURCE_ID),
- Response.SetData(
- safetySourceTestData.buildSafetySourceDataWithSummary(
- severityLevel = SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION,
- entryTitle = "Updated title",
- entrySummary = "Updated summary"
- )
- )
- )
- UiAutomatorUtils2.getUiDevice().rotate()
-
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
- waitAllTextNotDisplayed("Updated title", "Updated summary")
- }
- }
- }
-
- @Test
- fun issueCard_withMultipleGroups_onlyRelevantSubpageHasIssueCard() {
- /* The default attribution title for an issue card is same as the entry group title on the
- * homepage. This causes test flakiness as UiAutomator is unable to choose from duplicate
- * strings. To address that, an issue with a different attribution title is used here. */
- val sourceData = safetySourceTestData.informationWithIssueWithAttributionTitle
- val issue = sourceData.issues[0]
-
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
- val firstGroup = safetyCenterTestConfigs.multipleSourcesConfig.safetySourcesGroups[0]
- val secondGroup = safetyCenterTestConfigs.multipleSourcesConfig.safetySourcesGroups[1]
- safetyCenterTestHelper.setData(SOURCE_ID_3, sourceData)
-
- context.launchSafetyCenterActivity {
- // Verify that homepage has the issue card
- waitSourceIssueDisplayed(issue)
-
- // Verify that irrelevant subpage doesn't have the issue card
- openPageAndExit(context.getString(firstGroup.titleResId)) {
- waitSourceIssueNotDisplayed(issue)
- }
- // Verify that relevant subpage has the issue card
- openPageAndExit(context.getString(secondGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- }
- }
- }
-
- @Test
- fun issueCard_updateSafetySourceData_subpageDisplaysUpdatedIssue() {
- val initialDataToDisplay = safetySourceTestData.informationWithIssueWithAttributionTitle
- val updatedDataToDisplay = safetySourceTestData.criticalWithIssueWithAttributionTitle
-
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, initialDataToDisplay)
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(initialDataToDisplay.issues[0])
-
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, updatedDataToDisplay)
-
- waitSourceIssueDisplayed(updatedDataToDisplay.issues[0])
- }
- }
- }
-
- @Test
- fun issueCard_resolveIssueOnSubpage_issueDismisses() {
- val sourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val issue = sourceData.issues[0]
- val action = issue.actions[0]
-
- // Clear the data when action is triggered to simulate resolution.
- SafetySourceReceiver.setResponse(
- Request.ResolveAction(SINGLE_SOURCE_ID),
- Response.ClearData
- )
-
- context.launchSafetyCenterActivity(withReceiverPermission = true) {
- openPageAndExitAllowingRetries(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- waitButtonDisplayed(action.label) { it.click() }
-
- // Wait for success message to go away, verify issue no longer displayed
- waitAllTextNotDisplayed(action.successMessage)
- waitSourceIssueNotDisplayed(issue)
- }
- }
- }
-
- @Test
- fun issueCard_confirmDismissalOnSubpage_dismissesIssue() {
- val sourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val issue = sourceData.issues[0]
-
- context.launchSafetyCenterActivity {
- openPageAndExitAllowingRetries(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- clickDismissIssueCard()
-
- waitAllTextDisplayed("Dismiss this alert?")
- clickConfirmDismissal()
-
- waitSourceIssueNotDisplayed(issue)
- }
- }
- }
-
- @Test
- fun issueCard_dismissOnSubpageWithRotation_cancellationPersistsIssue() {
- val sourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val issue = sourceData.issues[0]
-
- context.launchSafetyCenterActivity {
- openPageAndExitAllowingRetries(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- clickDismissIssueCard()
- waitAllTextDisplayed("Dismiss this alert?")
-
- UiAutomatorUtils2.getUiDevice().rotate()
-
- waitAllTextDisplayed("Dismiss this alert?")
- waitButtonDisplayed("Cancel") { it.click() }
- waitSourceIssueDisplayed(issue)
- }
- }
- }
-
- @Test
- fun moreIssuesCard_expandOnSubpage_showsAdditionalCard() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
- val sourcesGroup = safetyCenterTestConfigs.multipleSourcesConfig.safetySourcesGroups.first()
- val firstSourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- val secondSourceData = safetySourceTestData.informationWithIssueWithAttributionTitle
- safetyCenterTestHelper.setData(SOURCE_ID_1, firstSourceData)
- safetyCenterTestHelper.setData(SOURCE_ID_2, secondSourceData)
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitCollapsedIssuesDisplayed(firstSourceData.issues[0], secondSourceData.issues[0])
-
- clickMoreIssuesCard()
-
- waitExpandedIssuesDisplayed(firstSourceData.issues[0], secondSourceData.issues[0])
- }
- }
- }
-
- @Test
- fun dismissedIssuesCard_expandWithOnlyDismissedIssues_showsAdditionalCard() {
- val sourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val issue = sourceData.issues[0]
-
- context.launchSafetyCenterActivity {
- openPageAndExitAllowingRetries(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- clickDismissIssueCard()
- waitAllTextDisplayed("Dismiss this alert?")
- clickConfirmDismissal()
- waitSourceIssueNotDisplayed(issue)
-
- waitDisplayed(By.text("Dismissed alerts")) { it.click() }
-
- waitAllTextDisplayed("Dismissed alerts")
- waitSourceIssueDisplayed(issue)
- }
- }
- }
-
- @Test
- fun dismissedIssuesCard_collapseWithOnlyDismissedIssues_hidesAdditionalCard() {
- val sourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val issue = sourceData.issues[0]
-
- context.launchSafetyCenterActivity {
- openPageAndExitAllowingRetries(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- clickDismissIssueCard()
- waitAllTextDisplayed("Dismiss this alert?")
- clickConfirmDismissal()
- waitSourceIssueNotDisplayed(issue)
-
- waitDisplayed(By.text("Dismissed alerts")) { it.click() }
- waitSourceIssueDisplayed(issue)
-
- waitDisplayed(By.text("Dismissed alerts")) { it.click() }
- waitSourceIssueNotDisplayed(issue)
- }
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolveIssue_successConfirmationShown() {
- SafetyCenterFlags.hideResolvedIssueUiTransitionDelay = TIMEOUT_LONG
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithAttributionTitle
- )
- prepareActionResponse(Response.ClearData)
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) {
- // Re-enable animations for this test as this is needed to show the success message.
- setAnimationsEnabled(true)
- it.click()
- }
-
- // Success message should show up if issue marked as resolved
- val successMessage = action.successMessage
- waitAllTextDisplayed(successMessage)
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolveIssue_issueDismisses() {
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithAttributionTitle
- )
- prepareActionResponse(Response.ClearData)
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) { it.click() }
-
- // Wait for success message to go away, verify issue no longer displayed
- val successMessage = action.successMessage
- waitAllTextNotDisplayed(successMessage)
- waitSourceIssueNotDisplayed(issue)
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolveIssue_withDialogClickYes_resolves() {
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithConfirmationWithAttributionTitle
- )
- prepareActionResponse(Response.ClearData)
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) { it.click() }
-
- waitAllTextDisplayed(SafetySourceTestData.CONFIRMATION_TITLE)
- waitButtonDisplayed(SafetySourceTestData.CONFIRMATION_YES) { it.click() }
-
- waitSourceIssueNotDisplayed(issue)
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolveIssue_withDialog_rotates_clickYes_resolves() {
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithConfirmationWithAttributionTitle
- )
- prepareActionResponse(Response.ClearData)
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) { it.click() }
-
- waitAllTextDisplayed(SafetySourceTestData.CONFIRMATION_TITLE)
-
- UiAutomatorUtils2.getUiDevice().rotate()
-
- waitAllTextDisplayed(SafetySourceTestData.CONFIRMATION_TITLE)
- waitButtonDisplayed(SafetySourceTestData.CONFIRMATION_YES) { it.click() }
-
- waitSourceIssueNotDisplayed(issue)
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolveIssue_withDialogClicksNo_cancels() {
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithConfirmationWithAttributionTitle
- )
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) { it.click() }
-
- waitAllTextDisplayed(SafetySourceTestData.CONFIRMATION_TITLE)
- waitButtonDisplayed(SafetySourceTestData.CONFIRMATION_NO) { it.click() }
-
- waitSourceIssueDisplayed(issue)
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolveIssue_noSuccessMessage_noResolutionUiShown_issueDismisses() {
- SafetyCenterFlags.hideResolvedIssueUiTransitionDelay = TIMEOUT_LONG
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithAttributionTitle
- )
- prepareActionResponse(Response.ClearData)
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) {
- // Re-enable animations for this test as this is needed to show the success message.
- setAnimationsEnabled(true)
- it.click()
- }
-
- waitSourceIssueNotDisplayed(issue)
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolvingInflightIssueFailed_issueRemains() {
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithAttributionTitle
- )
- prepareActionResponse(Response.Error)
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) { it.click() }
-
- waitSourceIssueDisplayed(issue)
- }
- }
-
- @Test
- fun dismissedIssuesCard_resolvingInFlightIssueTimesOut_issueRemains() {
- SafetyCenterFlags.resolveActionTimeout = TIMEOUT_SHORT
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithIssueWithAttributionTitle
- )
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) { it.click() }
-
- waitSourceIssueDisplayed(issue)
- }
- }
-
- @Test
- fun dismissedIssuesCard_clickingNonResolvingActionButton_redirectsToDifferentScreen() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- val (sourcesGroup, issue) =
- prepareSingleSourceGroupWithIssue(
- safetySourceTestData.criticalWithTestActivityRedirectWithAttributionTitle
- )
-
- checkOnDismissedIssue(sourcesGroup, issue) {
- val action = issue.actions[0]
- waitButtonDisplayed(action.label) { it.click() }
- waitButtonDisplayed("Exit test activity") { it.click() }
- }
- }
-
- @Test
- fun moreIssuesCard_expandWithDismissedIssues_showsAdditionalCards() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesInSingleGroupConfig)
-
- val firstSourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- val secondSourceData = safetySourceTestData.informationWithIssueWithAttributionTitle
- val thirdSourceData = safetySourceTestData.informationWithIssueWithAttributionTitle
-
- safetyCenterTestHelper.setData(SOURCE_ID_1, firstSourceData)
- safetyCenterTestHelper.setData(SOURCE_ID_2, secondSourceData)
- safetyCenterTestHelper.setData(SOURCE_ID_3, thirdSourceData)
-
- val sourcesGroup =
- safetyCenterTestConfigs.multipleSourcesInSingleGroupConfig.safetySourcesGroups.first()
- val issue = firstSourceData.issues[0]
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- clickDismissIssueCard()
- waitAllTextDisplayed("Dismiss this alert?")
- clickConfirmDismissal()
- waitSourceIssueNotDisplayed(issue)
-
- clickMoreIssuesCard()
-
- waitAllTextDisplayed(MORE_ISSUES_LABEL)
- waitAllTextDisplayed("Dismissed alerts")
- waitSourceIssueDisplayed(issue)
- }
- }
- }
-
- @Test
- fun moreIssuesCard_collapseWithDismissedIssues_hidesAdditionalCards() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesInSingleGroupConfig)
-
- val firstSourceData = safetySourceTestData.criticalWithIssueWithAttributionTitle
- val secondSourceData = safetySourceTestData.informationWithIssueWithAttributionTitle
- val thirdSourceData = safetySourceTestData.informationWithIssueWithAttributionTitle
-
- safetyCenterTestHelper.setData(SOURCE_ID_1, firstSourceData)
- safetyCenterTestHelper.setData(SOURCE_ID_2, secondSourceData)
- safetyCenterTestHelper.setData(SOURCE_ID_3, thirdSourceData)
-
- val sourcesGroup =
- safetyCenterTestConfigs.multipleSourcesInSingleGroupConfig.safetySourcesGroups.first()
- val issue = firstSourceData.issues[0]
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitSourceIssueDisplayed(issue)
- clickDismissIssueCard()
- clickConfirmDismissal()
- waitSourceIssueNotDisplayed(issue)
-
- clickMoreIssuesCard()
- waitSourceIssueDisplayed(issue)
-
- clickMoreIssuesCard()
- waitAllTextDisplayed(MORE_ISSUES_LABEL)
- waitAllTextNotDisplayed("Dismissed alerts")
- waitSourceIssueNotDisplayed(issue)
- }
- }
- }
-
- @Test
- fun brandChip_openSubpageFromHomepage_homepageReopensOnClick() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.information)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
-
- context.launchSafetyCenterActivity {
- waitGroupShownOnHomepage(context, sourcesGroup)
-
- clickOpenSubpage(context, sourcesGroup)
- waitPageTitleDisplayed(context.getString(sourcesGroup.titleResId))
- waitAllTextNotDisplayed(context.getString(sourcesGroup.summaryResId))
-
- clickSubpageBrandChip()
- waitGroupShownOnHomepage(context, sourcesGroup)
- }
- }
-
- @Test
- fun brandChip_openSubpageFromIntent_homepageOpensOnClick() {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, safetySourceTestData.information)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val extras = Bundle()
- extras.putString(EXTRA_SAFETY_SOURCES_GROUP_ID, sourcesGroup.id)
-
- context.launchSafetyCenterActivity(extras) {
- waitPageTitleDisplayed(context.getString(sourcesGroup.titleResId))
- waitAllTextNotDisplayed(context.getString(sourcesGroup.summaryResId))
-
- clickSubpageBrandChip()
- waitGroupShownOnHomepage(context, sourcesGroup)
- }
- }
-
- @Test
- fun settingsSearch_openWithGenericIntentExtra_showsGenericSubpage() {
- val config = safetyCenterTestConfigs.multipleSourcesConfig
- safetyCenterTestHelper.setConfig(config)
- val sourcesGroup = config.safetySourcesGroups.first()
- val source = sourcesGroup.safetySources.first()
- val preferenceKey = "${source.id}_personal"
- val extras = Bundle()
- extras.putString(EXTRA_SETTINGS_FRAGMENT_ARGS_KEY, preferenceKey)
-
- context.launchSafetyCenterActivity(extras) {
- waitPageTitleDisplayed(context.getString(sourcesGroup.titleResId))
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId)
- )
- }
- }
-
- @Test
- fun settingsSearch_openWithInvalidKey_showsHomepage() {
- val config = safetyCenterTestConfigs.singleSourceConfig
- val sourcesGroup = config.safetySourcesGroups.first()
- safetyCenterTestHelper.setConfig(config)
- val extras = Bundle()
- extras.putString(EXTRA_SETTINGS_FRAGMENT_ARGS_KEY, "invalid_preference_key")
-
- context.launchSafetyCenterActivity(extras) {
- waitPageTitleDisplayed("Security & privacy")
- waitGroupShownOnHomepage(context, sourcesGroup)
- }
- }
-
- @Test
- fun footerSummary_openGenericSubpageHavingFooter_showsExpectedText() {
- val config = safetyCenterTestConfigs.singleSourceConfig
- val sourcesGroup = config.safetySourcesGroups.first()
- val source: SafetySource = sourcesGroup.safetySources.first()
- safetyCenterTestHelper.setConfig(config)
-
- context.launchSafetyCenterActivity {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitAllTextDisplayed(
- context.getString(source.titleResId),
- context.getString(source.summaryResId),
- safetyCenterResourcesContext.getStringByName(
- "test_single_source_group_id_footer"
- )
- )
- }
- }
- }
-
- private fun prepareSingleSourceGroupWithIssue(
- sourceData: SafetySourceData
- ): Pair<SafetySourcesGroup, SafetySourceIssue> {
- safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig)
- safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, sourceData)
- val sourcesGroup = safetyCenterTestConfigs.singleSourceConfig.safetySourcesGroups.first()
- val issue = sourceData.issues[0]
- return sourcesGroup to issue
- }
-
- private fun prepareActionResponse(actionResponse: Response) {
- SafetySourceReceiver.setResponse(Request.ResolveAction(SINGLE_SOURCE_ID), actionResponse)
- }
-
- private fun checkOnDismissedIssue(
- sourcesGroup: SafetySourcesGroup,
- issue: SafetySourceIssue,
- block: () -> Unit
- ) {
- val safetyCenterIssueId = SafetyCenterTestData.issueId(SINGLE_SOURCE_ID, issue.id)
- safetyCenterTestHelper.dismissSafetyCenterIssue(safetyCenterIssueId)
-
- context.launchSafetyCenterActivity(withReceiverPermission = true) {
- openPageAndExit(context.getString(sourcesGroup.titleResId)) {
- waitDisplayed(By.text("Dismissed alerts")) { it.click() }
- waitSourceIssueDisplayed(issue)
-
- block()
- }
- }
- }
-
- companion object {
- private const val SAFETY_SOURCE_1_TITLE = "Safety Source 1 Title"
- private const val SAFETY_SOURCE_1_SUMMARY = "Safety Source 1 Summary"
- private const val SAFETY_SOURCE_2_TITLE = "Safety Source 2 Title"
- private const val SAFETY_SOURCE_2_SUMMARY = "Safety Source 2 Summary"
- private const val SAFETY_SOURCE_3_TITLE = "Safety Source 3 Title"
- private const val SAFETY_SOURCE_3_SUMMARY = "Safety Source 3 Summary"
- private const val EXTRA_SETTINGS_FRAGMENT_ARGS_KEY = ":settings:fragment_args_key"
- }
-}