Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ class QSTileLoggerTest : SysuiTestCase() { underTest.logUserActionRejectedByPolicy( QSTileUserAction.Click(null), TileSpec.create("test_spec"), "test_restriction", ) assertThat(logBuffer.getStringBuffer()).contains("tile click: rejected by policy") Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,9 @@ class QSTileViewModelTest : SysuiTestCase() { @Mock private lateinit var qsTileAnalytics: QSTileAnalytics private val tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted("test_restriction") } QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf("test_restriction")) } private val userRepository = FakeUserRepository() private val tileDataInteractor = FakeQSTileDataInteractor<String>() Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt +86 −10 Original line number Diff line number Diff line Loading @@ -16,18 +16,17 @@ package com.android.systemui.qs.tiles.viewmodel import android.platform.test.annotations.EnabledOnRavenwood import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import com.android.settingslib.RestrictedLockUtils import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.ENABLED_RESTRICTION import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper Loading @@ -54,7 +53,6 @@ import org.mockito.MockitoAnnotations /** Tests all possible [QSTileUserAction]s. If you need */ @MediumTest @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) @OptIn(ExperimentalCoroutinesApi::class) class QSTileViewModelUserInputTest : SysuiTestCase() { Loading @@ -65,8 +63,10 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { // TODO(b/299909989): this should be parametrised. b/299096521 blocks this. private val userAction: QSTileUserAction = QSTileUserAction.Click(null) private val tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted("test_restriction") } private var tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf(ENABLED_RESTRICTION)) } private val userRepository = FakeUserRepository() private val tileDataInteractor = FakeQSTileDataInteractor<String>() Loading Loading @@ -112,11 +112,42 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { @Test fun disabledByPolicyUserInputIsSkipped() = testScope.runTest { tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf(DISABLED_RESTRICTION)) } underTest = createViewModel(testScope) underTest.state.launchIn(backgroundScope) disabledByPolicyInteractor.policyResult = DisabledByPolicyInteractor.PolicyResult.TileDisabled( RestrictedLockUtils.EnforcedAdmin() runCurrent() underTest.onActionPerformed(userAction) runCurrent() assertThat(tileDataInteractor.triggers.last()) .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java) verify(qsTileLogger) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(DISABLED_RESTRICTION) ) verify(qsTileAnalytics, never()).trackUserAction(any(), any()) } @Test fun disabledByPolicySecondRestriction_userInputIsSkipped() = testScope.runTest { tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf(ENABLED_RESTRICTION, DISABLED_RESTRICTION)) } underTest = createViewModel(testScope) underTest.state.launchIn(backgroundScope) runCurrent() underTest.onActionPerformed(userAction) Loading @@ -125,7 +156,52 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { assertThat(tileDataInteractor.triggers.last()) .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java) verify(qsTileLogger) .logUserActionRejectedByPolicy(eq(userAction), eq(tileConfig.tileSpec)) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(DISABLED_RESTRICTION) ) verify(qsTileAnalytics, never()).trackUserAction(any(), any()) } /** This tests that the policies are applied sequentially */ @Test fun disabledByPolicySecondRestriction_onlyFirstIsTriggered() = testScope.runTest { tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted( listOf( DISABLED_RESTRICTION, FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2 ) ) } underTest = createViewModel(testScope) underTest.state.launchIn(backgroundScope) runCurrent() underTest.onActionPerformed(userAction) runCurrent() assertThat(tileDataInteractor.triggers.last()) .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java) verify(qsTileLogger) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(DISABLED_RESTRICTION) ) verify(qsTileLogger, never()) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2) ) verify(qsTileAnalytics, never()).trackUserAction(any(), any()) } Loading packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt +2 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ constructor( fun logUserActionRejectedByPolicy( userAction: QSTileUserAction, tileSpec: TileSpec, restriction: String, ) { tileSpec .getLogBuffer() Loading @@ -95,7 +96,7 @@ constructor( tileSpec.getLogTag(), LogLevel.DEBUG, { str1 = userAction.toLogString() }, { "tile $str1: rejected by policy" } { "tile $str1: rejected by policy, restriction: $restriction" } ) } Loading packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt +11 −6 Original line number Diff line number Diff line Loading @@ -178,7 +178,8 @@ class QSTileViewModelImpl<DATA_TYPE>( /** * Creates a user input flow which: * - filters false inputs with [falsingManager] * - takes care of a tile being disable by policy using [disabledByPolicyInteractor] * - takes care of a tile being disable by policy using [disabledByPolicyInteractor]. The * restrictions will be checked sequentially and the first one to block will be considered. * - notifies [userActionInteractor] about the action * - logs it accordingly using [qsTileLogger] and [qsTileAnalytics] * Loading @@ -201,18 +202,22 @@ class QSTileViewModelImpl<DATA_TYPE>( .onEach { userActionInteractor().handleInput(it.input) } .flowOn(backgroundDispatcher) /** * The restrictions will be checked sequentially and the first one to block will be considered. */ private fun Flow<QSTileUserAction>.filterByPolicy(user: UserHandle): Flow<QSTileUserAction> = config.policy.let { policy -> when (policy) { is QSTilePolicy.NoRestrictions -> this@filterByPolicy is QSTilePolicy.Restricted -> filter { action -> val result = disabledByPolicyInteractor.isDisabled(user, policy.userRestriction) !disabledByPolicyInteractor.handlePolicyResult(result).also { isDisabled -> if (isDisabled) { qsTileLogger.logUserActionRejectedByPolicy(action, spec) policy.userRestrictions.none { val result = disabledByPolicyInteractor.isDisabled(user, it) val handleResult = disabledByPolicyInteractor.handlePolicyResult(result) if (handleResult) { qsTileLogger.logUserActionRejectedByPolicy(action, spec, it) } handleResult } } } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ class QSTileLoggerTest : SysuiTestCase() { underTest.logUserActionRejectedByPolicy( QSTileUserAction.Click(null), TileSpec.create("test_spec"), "test_restriction", ) assertThat(logBuffer.getStringBuffer()).contains("tile click: rejected by policy") Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt +3 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,9 @@ class QSTileViewModelTest : SysuiTestCase() { @Mock private lateinit var qsTileAnalytics: QSTileAnalytics private val tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted("test_restriction") } QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf("test_restriction")) } private val userRepository = FakeUserRepository() private val tileDataInteractor = FakeQSTileDataInteractor<String>() Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt +86 −10 Original line number Diff line number Diff line Loading @@ -16,18 +16,17 @@ package com.android.systemui.qs.tiles.viewmodel import android.platform.test.annotations.EnabledOnRavenwood import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import com.android.settingslib.RestrictedLockUtils import com.android.systemui.SysuiTestCase import com.android.systemui.classifier.FalsingManagerFake import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.ENABLED_RESTRICTION import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper Loading @@ -54,7 +53,6 @@ import org.mockito.MockitoAnnotations /** Tests all possible [QSTileUserAction]s. If you need */ @MediumTest @EnabledOnRavenwood @RunWith(AndroidJUnit4::class) @OptIn(ExperimentalCoroutinesApi::class) class QSTileViewModelUserInputTest : SysuiTestCase() { Loading @@ -65,8 +63,10 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { // TODO(b/299909989): this should be parametrised. b/299096521 blocks this. private val userAction: QSTileUserAction = QSTileUserAction.Click(null) private val tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted("test_restriction") } private var tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf(ENABLED_RESTRICTION)) } private val userRepository = FakeUserRepository() private val tileDataInteractor = FakeQSTileDataInteractor<String>() Loading Loading @@ -112,11 +112,42 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { @Test fun disabledByPolicyUserInputIsSkipped() = testScope.runTest { tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf(DISABLED_RESTRICTION)) } underTest = createViewModel(testScope) underTest.state.launchIn(backgroundScope) disabledByPolicyInteractor.policyResult = DisabledByPolicyInteractor.PolicyResult.TileDisabled( RestrictedLockUtils.EnforcedAdmin() runCurrent() underTest.onActionPerformed(userAction) runCurrent() assertThat(tileDataInteractor.triggers.last()) .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java) verify(qsTileLogger) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(DISABLED_RESTRICTION) ) verify(qsTileAnalytics, never()).trackUserAction(any(), any()) } @Test fun disabledByPolicySecondRestriction_userInputIsSkipped() = testScope.runTest { tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted(listOf(ENABLED_RESTRICTION, DISABLED_RESTRICTION)) } underTest = createViewModel(testScope) underTest.state.launchIn(backgroundScope) runCurrent() underTest.onActionPerformed(userAction) Loading @@ -125,7 +156,52 @@ class QSTileViewModelUserInputTest : SysuiTestCase() { assertThat(tileDataInteractor.triggers.last()) .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java) verify(qsTileLogger) .logUserActionRejectedByPolicy(eq(userAction), eq(tileConfig.tileSpec)) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(DISABLED_RESTRICTION) ) verify(qsTileAnalytics, never()).trackUserAction(any(), any()) } /** This tests that the policies are applied sequentially */ @Test fun disabledByPolicySecondRestriction_onlyFirstIsTriggered() = testScope.runTest { tileConfig = QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted( listOf( DISABLED_RESTRICTION, FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2 ) ) } underTest = createViewModel(testScope) underTest.state.launchIn(backgroundScope) runCurrent() underTest.onActionPerformed(userAction) runCurrent() assertThat(tileDataInteractor.triggers.last()) .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java) verify(qsTileLogger) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(DISABLED_RESTRICTION) ) verify(qsTileLogger, never()) .logUserActionRejectedByPolicy( eq(userAction), eq(tileConfig.tileSpec), eq(FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2) ) verify(qsTileAnalytics, never()).trackUserAction(any(), any()) } Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt +2 −1 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ constructor( fun logUserActionRejectedByPolicy( userAction: QSTileUserAction, tileSpec: TileSpec, restriction: String, ) { tileSpec .getLogBuffer() Loading @@ -95,7 +96,7 @@ constructor( tileSpec.getLogTag(), LogLevel.DEBUG, { str1 = userAction.toLogString() }, { "tile $str1: rejected by policy" } { "tile $str1: rejected by policy, restriction: $restriction" } ) } Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt +11 −6 Original line number Diff line number Diff line Loading @@ -178,7 +178,8 @@ class QSTileViewModelImpl<DATA_TYPE>( /** * Creates a user input flow which: * - filters false inputs with [falsingManager] * - takes care of a tile being disable by policy using [disabledByPolicyInteractor] * - takes care of a tile being disable by policy using [disabledByPolicyInteractor]. The * restrictions will be checked sequentially and the first one to block will be considered. * - notifies [userActionInteractor] about the action * - logs it accordingly using [qsTileLogger] and [qsTileAnalytics] * Loading @@ -201,18 +202,22 @@ class QSTileViewModelImpl<DATA_TYPE>( .onEach { userActionInteractor().handleInput(it.input) } .flowOn(backgroundDispatcher) /** * The restrictions will be checked sequentially and the first one to block will be considered. */ private fun Flow<QSTileUserAction>.filterByPolicy(user: UserHandle): Flow<QSTileUserAction> = config.policy.let { policy -> when (policy) { is QSTilePolicy.NoRestrictions -> this@filterByPolicy is QSTilePolicy.Restricted -> filter { action -> val result = disabledByPolicyInteractor.isDisabled(user, policy.userRestriction) !disabledByPolicyInteractor.handlePolicyResult(result).also { isDisabled -> if (isDisabled) { qsTileLogger.logUserActionRejectedByPolicy(action, spec) policy.userRestrictions.none { val result = disabledByPolicyInteractor.isDisabled(user, it) val handleResult = disabledByPolicyInteractor.handlePolicyResult(result) if (handleResult) { qsTileLogger.logUserActionRejectedByPolicy(action, spec, it) } handleResult } } } Loading