diff options
Diffstat (limited to 'tests/hostside')
9 files changed, 145 insertions, 68 deletions
diff --git a/tests/hostside/safetycenter/Android.bp b/tests/hostside/safetycenter/Android.bp index b86ee9bee..10258f95b 100644 --- a/tests/hostside/safetycenter/Android.bp +++ b/tests/hostside/safetycenter/Android.bp @@ -28,6 +28,7 @@ java_test_host { libs: [ "tradefed", "junit", + "compatibility-host-util", ], static_libs: [ "cts-statsd-atom-host-test-utils", diff --git a/tests/hostside/safetycenter/AndroidTest.xml b/tests/hostside/safetycenter/AndroidTest.xml index 09ddf9d84..a28b70c3c 100644 --- a/tests/hostside/safetycenter/AndroidTest.xml +++ b/tests/hostside/safetycenter/AndroidTest.xml @@ -28,9 +28,12 @@ aren't polluted by `BOOT_COMPLETED` or similar broadcasts still being delivered, which causes our `ActivityManager#waitForBroadcastIdle()` calls to timeout. --> <option name="run-command" value="am wait-for-broadcast-idle" /> + <option name="run-command" value="am wait-for-broadcast-barrier" /> <!-- Disable syncing to prevent overwriting flags during testing. --> <option name="run-command" value="device_config set_sync_disabled_for_tests persistent" /> <option name="teardown-command" value="device_config set_sync_disabled_for_tests none" /> + <!-- Dismiss any system dialogs (e.g. crashes, ANR). --> + <option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS --receiver-foreground" /> </target_preparer> <target_preparer class="com.android.compatibility.common.tradefed.targetprep.StayAwakePreparer" /> diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt index c72166c65..784701b8a 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterInteractionLoggingHelperTests.kt @@ -26,8 +26,9 @@ import com.android.safetycenter.testing.SafetyCenterActivityLauncher.openPageAnd import com.android.safetycenter.testing.SafetyCenterFlags import com.android.safetycenter.testing.SafetyCenterTestConfigs import com.android.safetycenter.testing.SafetyCenterTestHelper -import org.junit.After +import com.android.safetycenter.testing.SafetyCenterTestRule import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -47,17 +48,13 @@ class SafetyCenterInteractionLoggingHelperTests { private val safetyCenterTestHelper = SafetyCenterTestHelper(context) private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context) + @get:Rule val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper) + @Before fun setUp() { - safetyCenterTestHelper.setup() SafetyCenterFlags.showSubpages = true } - @After - fun tearDown() { - safetyCenterTestHelper.reset() - } - @Test fun openSafetyCenter() { context.launchSafetyCenterActivity {} diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt index f4677cfed..458516379 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetyCenterNotificationLoggingHelperTests.kt @@ -25,9 +25,10 @@ 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.SafetyCenterTestHelper +import com.android.safetycenter.testing.SafetyCenterTestRule import com.android.safetycenter.testing.SafetySourceTestData -import org.junit.After import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -48,20 +49,16 @@ class SafetyCenterNotificationLoggingHelperTests { private val safetySourceTestData = SafetySourceTestData(context) private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context) + @get:Rule val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper) + @Before fun setUp() { - safetyCenterTestHelper.setup() SafetyCenterFlags.notificationsEnabled = true SafetyCenterFlags.notificationsAllowedSources = setOf(SINGLE_SOURCE_ID) SafetyCenterFlags.allowStatsdLogging = true safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig) } - @After - fun tearDown() { - safetyCenterTestHelper.reset() - } - @Test fun sendNotification() { safetyCenterTestHelper.setData(SINGLE_SOURCE_ID, newTestDataWithNotifiableIssue()) diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt index d0e6dd430..4d945aad7 100644 --- a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt +++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt @@ -23,16 +23,27 @@ import android.safetycenter.SafetySourceErrorDetails import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.compatibility.common.util.SystemUtil -import com.android.safetycenter.testing.* +import com.android.safetycenter.testing.Coroutines.TIMEOUT_SHORT import com.android.safetycenter.testing.SafetyCenterApisWithShellPermissions.reportSafetySourceErrorWithPermission +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.SafetyCenterTestConfigs.Companion.SOURCE_ID_3 +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.SafetySourceReceiver.Companion.executeSafetyCenterIssueActionWithPermissionAndWait import com.android.safetycenter.testing.SafetySourceReceiver.Companion.refreshSafetySourcesWithReceiverPermissionAndWait -import org.junit.After +import com.android.safetycenter.testing.SafetySourceTestData +import com.android.safetycenter.testing.SafetySourceTestData.Companion.CRITICAL_ISSUE_ACTION_ID +import com.android.safetycenter.testing.SafetySourceTestData.Companion.CRITICAL_ISSUE_ID import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -44,18 +55,14 @@ class SafetySourceStateCollectedLoggingHelperTests { private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context) private val safetyCenterManager = context.getSystemService(SafetyCenterManager::class.java)!! + @get:Rule val safetyCenterTestRule = SafetyCenterTestRule(safetyCenterTestHelper) + @Before fun setUp() { - safetyCenterTestHelper.setup() SafetyCenterFlags.allowStatsdLogging = true safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig) } - @After - fun tearDown() { - safetyCenterTestHelper.reset() - } - @Test fun triggerStatsPull() { val label = 1 // Arbitrary label in [0, 16) @@ -124,13 +131,11 @@ class SafetySourceStateCollectedLoggingHelperTests { @Test fun refreshAllSources_reasonPageOpen_oneSuccessOneErrorOneTimeout() { - SafetyCenterFlags.setAllRefreshTimeoutsTo(Coroutines.TIMEOUT_SHORT) simulateRefresh(Response.SetData(safetySourceTestData.information), Response.Error, null) } @Test fun refreshAllSources_reasonButtonClick_oneSuccessOneErrorOneTimeout() { - SafetyCenterFlags.setAllRefreshTimeoutsTo(Coroutines.TIMEOUT_SHORT) simulateRefresh( Response.SetData(safetySourceTestData.information), Response.Error, @@ -139,6 +144,16 @@ class SafetySourceStateCollectedLoggingHelperTests { ) } + @Test + fun resolvingAction_success() { + simulateResolvingActionWith(Response.SetData(safetySourceTestData.information)) + } + + @Test + fun resolvingAction_error() { + simulateResolvingActionWith(Response.Error) + } + private fun simulateRefresh( source1Response: Response?, source2Response: Response?, @@ -155,8 +170,34 @@ class SafetySourceStateCollectedLoggingHelperTests { SafetySourceReceiver.setResponse(Request.Refresh(SOURCE_ID_3), source3Response) } + val atLeastOneTimeout = + source1Response == null || source2Response == null || source3Response == null + if (atLeastOneTimeout) { + SafetyCenterFlags.setAllRefreshTimeoutsTo(TIMEOUT_SHORT) + } + + // Refresh sources and wait until the refresh has fully completed / timed out to ensure that + // things are logged. val listener = safetyCenterTestHelper.addListener() safetyCenterManager.refreshSafetySourcesWithReceiverPermissionAndWait(refreshReason) listener.waitForSafetyCenterRefresh() } + + private fun simulateResolvingActionWith(response: Response) { + safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.singleSourceConfig) + safetyCenterTestHelper.setData( + SINGLE_SOURCE_ID, + safetySourceTestData.criticalWithResolvingGeneralIssue + ) + SafetySourceReceiver.setResponse(Request.ResolveAction(SINGLE_SOURCE_ID), response) + + safetyCenterManager.executeSafetyCenterIssueActionWithPermissionAndWait( + SafetyCenterTestData.issueId(SINGLE_SOURCE_ID, CRITICAL_ISSUE_ID), + SafetyCenterTestData.issueActionId( + SINGLE_SOURCE_ID, + CRITICAL_ISSUE_ID, + CRITICAL_ISSUE_ACTION_ID + ) + ) + } } diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt index 5ef8ed84a..5fe9e0a2a 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt @@ -20,6 +20,7 @@ import android.cts.statsdatom.lib.ConfigUtils import android.cts.statsdatom.lib.ReportUtils import android.safetycenter.hostside.rules.HelperAppRule import android.safetycenter.hostside.rules.RequireSafetyCenterRule +import com.android.compatibility.common.util.ApiLevelUtil import com.android.os.AtomsProto.Atom import com.android.os.AtomsProto.SafetyCenterInteractionReported import com.android.os.AtomsProto.SafetyCenterInteractionReported.Action @@ -28,23 +29,19 @@ import com.android.tradefed.testtype.DeviceJUnit4ClassRunner import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test import com.google.common.truth.Truth.assertThat import org.junit.After +import org.junit.Assume.assumeTrue import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test -import org.junit.rules.RuleChain import org.junit.runner.RunWith /** Host-side tests for Safety Center statsd logging. */ @RunWith(DeviceJUnit4ClassRunner::class) class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { - private val safetyCenterRule = RequireSafetyCenterRule(this) - private val helperAppRule = HelperAppRule(this, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME) - - @Rule - @JvmField - val rules: RuleChain = RuleChain.outerRule(safetyCenterRule).around(helperAppRule) + @get:Rule(order = 1) val safetyCenterRule = RequireSafetyCenterRule(this) + @get:Rule(order = 2) + val helperAppRule = HelperAppRule(this, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME) @Before fun setUp() { @@ -75,6 +72,8 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { @Test fun sendNotification_recordsNotificationPostedEvent() { + assumeAtLeastUpsideDownCake("Safety Center notification APIs require Android U+") + helperAppRule.runTest( testClassName = ".SafetyCenterNotificationLoggingHelperTests", testMethodName = "sendNotification" @@ -89,6 +88,8 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { @Test fun openSubpageFromIntentExtra_recordsEventWithUnknownNavigationSource() { + assumeAtLeastUpsideDownCake("Safety Center subpages require Android U+") + helperAppRule.runTest(TEST_CLASS_NAME, testMethodName = "openSubpageFromIntentExtra") val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) @@ -103,25 +104,24 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { } @Test - @Ignore - // TODO(b/278202773): Fix/de-flake this test fun openSubpageFromHomepage_recordsEventWithSafetyCenterNavigationSource() { + assumeAtLeastUpsideDownCake("Safety Center subpages require Android U+") + helperAppRule.runTest(TEST_CLASS_NAME, testMethodName = "openSubpageFromHomepage") val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) + val subpageViewedEvent = safetyCenterViewedAtoms.find { it.viewType == ViewType.SUBPAGE } - assertThat(safetyCenterViewedAtoms.map { it.viewType }) - .containsExactly(ViewType.FULL, ViewType.SUBPAGE, ViewType.FULL) - .inOrder() - assertThat(safetyCenterViewedAtoms[1].navigationSource) + assertThat(subpageViewedEvent).isNotNull() + assertThat(subpageViewedEvent!!.navigationSource) .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SAFETY_CENTER) assertThat(safetyCenterViewedAtoms.map { it.sessionId }.distinct()).hasSize(1) } @Test - @Ignore - // TODO(b/278202773): Fix/de-flake this test fun openSubpageFromSettingsSearch_recordsEventWithSettingsNavigationSource() { + assumeAtLeastUpsideDownCake("Safety Center subpages require Android U+") + helperAppRule.runTest(TEST_CLASS_NAME, testMethodName = "openSubpageFromSettingsSearch") val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED) @@ -142,6 +142,10 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() { .mapNotNull { it.atom.safetyCenterInteractionReported } .filter { it.action == action } + private fun assumeAtLeastUpsideDownCake(message: String) { + assumeTrue(message, ApiLevelUtil.isAtLeast(device, 34)) + } + private companion object { const val TEST_CLASS_NAME = ".SafetyCenterInteractionLoggingHelperTests" } diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterSystemEventReportedLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterSystemEventReportedLoggingHostTest.kt index 65e47fa91..2589c7a47 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterSystemEventReportedLoggingHostTest.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterSystemEventReportedLoggingHostTest.kt @@ -31,18 +31,14 @@ import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.RuleChain import org.junit.runner.RunWith @RunWith(DeviceJUnit4ClassRunner::class) class SafetyCenterSystemEventReportedLoggingHostTest : BaseHostJUnit4Test() { - private val safetyCenterRule = RequireSafetyCenterRule(this) - private val helperAppRule = HelperAppRule(this, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME) - - @Rule - @JvmField - val rules: RuleChain = RuleChain.outerRule(safetyCenterRule).around(helperAppRule) + @get:Rule(order = 1) val safetyCenterRule = RequireSafetyCenterRule(this) + @get:Rule(order = 2) + val helperAppRule = HelperAppRule(this, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME) @Before fun setUp() { @@ -143,6 +139,7 @@ class SafetyCenterSystemEventReportedLoggingHostTest : BaseHostJUnit4Test() { .that(systemEventAtoms.count { it.refreshReason == REFRESH_REASON_BUTTON_CLICK }) } + @Test fun refreshAllSources_firstTime_allSourcesSuccessful_dataChangedTrueForAll() { helperAppRule.runTest( ".SafetySourceStateCollectedLoggingHelperTests", @@ -183,18 +180,50 @@ class SafetyCenterSystemEventReportedLoggingHostTest : BaseHostJUnit4Test() { @Test fun refreshAllSources_secondTime_someSourcesChanged_dataChangedCorrect() { helperAppRule.runTest( - ".SafetySourceStateCollectedLoggingHelperTests", - "refreshAllSources_twiceDifferentData_onlySource1Unchanged" + ".SafetySourceStateCollectedLoggingHelperTests", + "refreshAllSources_twiceDifferentData_onlySource1Unchanged" ) val systemEventAtoms = - ReportUtils.getEventMetricDataList(device).mapNotNull { - it.atom.safetyCenterSystemEventReported - } + ReportUtils.getEventMetricDataList(device).mapNotNull { + it.atom.safetyCenterSystemEventReported + } assertWithMessage("the number of atoms with dataChanged=false") - .that(systemEventAtoms.count { !it.dataChanged }) - .isEqualTo(1) // Only source 1 + .that(systemEventAtoms.count { !it.dataChanged }) + .isEqualTo(1) // Only source 1 + } + + @Test + fun resolveAction_success_resolvingActionSuccessEvent() { + helperAppRule.runTest( + ".SafetySourceStateCollectedLoggingHelperTests", + "resolvingAction_success" + ) + + val resolvingActionEvent = + ReportUtils.getEventMetricDataList(device) + .mapNotNull { it.atom.safetyCenterSystemEventReported } + .single { it.eventType == EventType.INLINE_ACTION } + + assertThat(resolvingActionEvent.result).isEqualTo(Result.SUCCESS) + assertThat(resolvingActionEvent.encodedIssueTypeId).isNotEqualTo(0) + } + + @Test + fun resolveAction_error_resolvingActionErrorEvent() { + helperAppRule.runTest( + ".SafetySourceStateCollectedLoggingHelperTests", + "resolvingAction_error" + ) + + val resolvingActionEvent = + ReportUtils.getEventMetricDataList(device) + .mapNotNull { it.atom.safetyCenterSystemEventReported } + .single { it.eventType == EventType.INLINE_ACTION } + + assertThat(resolvingActionEvent.result).isEqualTo(Result.ERROR) + assertThat(resolvingActionEvent.encodedIssueTypeId).isNotEqualTo(0) } companion object { diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt index 22a380e12..a86041b5b 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt @@ -29,19 +29,15 @@ import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.RuleChain import org.junit.runner.RunWith /** Host-side tests for Safety Center statsd logging. */ @RunWith(DeviceJUnit4ClassRunner::class) class SafetySourceStateCollectedLoggingHostTest : BaseHostJUnit4Test() { - private val safetyCenterRule = RequireSafetyCenterRule(this) - private val helperAppRule = HelperAppRule(this, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME) - - @Rule - @JvmField - val rules: RuleChain = RuleChain.outerRule(safetyCenterRule).around(helperAppRule) + @get:Rule(order = 1) val safetyCenterRule = RequireSafetyCenterRule(this) + @get:Rule(order = 2) + val helperAppRule = HelperAppRule(this, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME) @Before fun setUp() { @@ -66,8 +62,10 @@ class SafetySourceStateCollectedLoggingHostTest : BaseHostJUnit4Test() { val sourceStateAtoms = getSafetySourceStateCollectedAtoms() + // This assertion purposefully uses containsAtLeast and not containsExact because on test + // devices with multiple primary users there will be multiple atoms per source. assertThat(sourceStateAtoms.map { it.encodedSafetySourceId }) - .containsExactly( + .containsAtLeast( SOURCE_1_ENCODED_SOURCE_ID, SOURCE_2_ENCODED_SOURCE_ID, SOURCE_3_ENCODED_SOURCE_ID diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt index 809fe5f0f..edf76e888 100644 --- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt +++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/rules/RequireSafetyCenterRule.kt @@ -28,10 +28,10 @@ import org.junit.runners.model.Statement class RequireSafetyCenterRule(private val hostTestClass: BaseHostJUnit4Test) : TestRule { private val safetyCenterSupported: Boolean by lazy { - executeShellCommandOrThrow("cmd safety_center supported").toBoolean() + shellCommandStdoutOrThrow("cmd safety_center supported").toBooleanStrict() } private val safetyCenterEnabled: Boolean by lazy { - executeShellCommandOrThrow("cmd safety_center enabled").toBoolean() + shellCommandStdoutOrThrow("cmd safety_center enabled").toBooleanStrict() } override fun apply(base: Statement, description: Description): Statement { @@ -45,13 +45,20 @@ class RequireSafetyCenterRule(private val hostTestClass: BaseHostJUnit4Test) : T } /** Returns the package name of Safety Center on the test device. */ - fun getSafetyCenterPackageName(): String = - executeShellCommandOrThrow("cmd safety_center package-name") + fun getSafetyCenterPackageName(): String { + return shellCommandStdoutOrThrow("cmd safety_center package-name") + } - private fun executeShellCommandOrThrow(command: String): String { + private fun shellCommandStdoutOrThrow(command: String): String { val result = hostTestClass.device.executeShellV2Command(command) if (result.status != CommandStatus.SUCCESS) { - throw IOException("$command exited with status ${result.exitCode}") + throw IOException( + """Host-side test failed to execute adb shell command on test device. + |Command '$command' exited with status code ${result.exitCode}. + |This probably means the test device does not have a compatible version of + |the Permission Mainline module. Please check the test configuration.""" + .trimMargin("|") + ) } return result.stdout.trim() } |