diff options
8 files changed, 144 insertions, 50 deletions
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt index ea6a2720c512..7466f95e3fb8 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt @@ -41,8 +41,6 @@ import com.android.settingslib.spaprivileged.model.app.AppRecord import com.android.settingslib.spaprivileged.model.app.IPackageManagers import com.android.settingslib.spaprivileged.model.app.PackageManagers import com.android.settingslib.spaprivileged.model.app.toRoute -import com.android.settingslib.spaprivileged.model.enterprise.EnhancedConfirmation -import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderFactory import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreference @@ -155,12 +153,12 @@ internal fun <T : AppRecord> TogglePermissionAppListModel<T>.TogglePermissionApp override val changeable = { isChangeable } override val onCheckedChange: (Boolean) -> Unit = { setAllowed(record, it) } } - val restrictions = Restrictions(userId = userId, - keys = switchRestrictionKeys, - enhancedConfirmation = enhancedConfirmationKey?.let { EnhancedConfirmation( - key = it, - packageName = packageName) }) - RestrictedSwitchPreference(switchModel, restrictions, restrictionsProviderFactory) + RestrictedSwitchPreference( + model = switchModel, + restrictions = getRestrictions(userId, packageName), + ifBlockedByAdminOverrideCheckedValueTo = switchifBlockedByAdminOverrideCheckedValueTo, + restrictionsProviderFactory = restrictionsProviderFactory, + ) InfoPageAdditionalContent(record, isAllowed) } } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt index 627b248e75b9..d2867af1eda6 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt @@ -26,6 +26,8 @@ import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.rememberContext import com.android.settingslib.spa.framework.util.asyncMapItem import com.android.settingslib.spaprivileged.model.app.AppRecord +import com.android.settingslib.spaprivileged.model.enterprise.EnhancedConfirmation +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import kotlinx.coroutines.flow.Flow /** @@ -38,6 +40,16 @@ interface TogglePermissionAppListModel<T : AppRecord> { val switchRestrictionKeys: List<String> get() = emptyList() + /** + * If this is not null, and on a switch UI restricted by admin, the switch's checked status will + * be overridden. + * + * And if there is an admin summary, such as "Enabled by admin" or "Disabled by admin", will + * also be overridden. + */ + val switchifBlockedByAdminOverrideCheckedValueTo: Boolean? + get() = null + val enhancedConfirmationKey: String? get() = null @@ -101,6 +113,16 @@ fun <T : AppRecord> TogglePermissionAppListModel<T>.isChangeableWithSystemUidChe record: T, ): Boolean = !record.isSystemOrRootUid() && isChangeable(record) +fun <T : AppRecord> TogglePermissionAppListModel<T>.getRestrictions( + userId: Int, + packageName: String, +) = + Restrictions( + userId = userId, + keys = switchRestrictionKeys, + enhancedConfirmation = + enhancedConfirmationKey?.let { key -> EnhancedConfirmation(key, packageName) }, + ) interface TogglePermissionAppListProvider { val permissionType: String diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt index 57102ba9ea46..ec44d2af4ffa 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt @@ -42,8 +42,6 @@ import com.android.settingslib.spaprivileged.framework.compose.getPlaceholder import com.android.settingslib.spaprivileged.model.app.AppListModel import com.android.settingslib.spaprivileged.model.app.AppRecord import com.android.settingslib.spaprivileged.model.app.userId -import com.android.settingslib.spaprivileged.model.enterprise.EnhancedConfirmation -import com.android.settingslib.spaprivileged.model.enterprise.Restrictions import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderFactory import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl import com.android.settingslib.spaprivileged.model.enterprise.rememberRestrictedMode @@ -151,23 +149,19 @@ internal class TogglePermissionInternalAppListModel<T : AppRecord>( @Composable fun getSummary(record: T): () -> String { - val restrictions = remember(record.app.userId, record.app.packageName) { - Restrictions( + val restrictions = + listModel.getRestrictions( userId = record.app.userId, - keys = listModel.switchRestrictionKeys, - enhancedConfirmation = listModel.enhancedConfirmationKey?.let { - EnhancedConfirmation( - key = it, - packageName = record.app.packageName) - }) - } + packageName = record.app.packageName, + ) val restrictedMode by restrictionsProviderFactory.rememberRestrictedMode(restrictions) val allowed = listModel.isAllowed(record) return RestrictedSwitchPreferenceModel.getSummary( context = context, - restrictedModeSupplier = { restrictedMode }, summaryIfNoRestricted = { getSummaryIfNoRestricted(allowed()) }, - checked = allowed, + checkedIfNoRestricted = allowed, + checkedIfBlockedByAdmin = listModel.switchifBlockedByAdminOverrideCheckedValueTo, + restrictedModeSupplier = { restrictedMode }, ) } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt index cd720252e485..5fec110351bf 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt @@ -25,12 +25,25 @@ import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvid import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl import com.android.settingslib.spaprivileged.template.preference.RestrictedSwitchPreferenceModel.Companion.RestrictedSwitchWrapper +/** + * @param ifBlockedByAdminOverrideCheckedValueTo if this is not null and there is an admin + * restriction, the switch's checked status will be overridden. + * + * And if there is an admin summary, such as "Enabled by admin" or "Disabled by admin", will also + * be overridden. + */ @Composable fun RestrictedSwitchPreference( model: SwitchPreferenceModel, restrictions: Restrictions, + ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null, ) { - RestrictedSwitchPreference(model, restrictions, ::RestrictionsProviderImpl) + RestrictedSwitchPreference( + model = model, + restrictions = restrictions, + ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo, + restrictionsProviderFactory = ::RestrictionsProviderImpl, + ) } @VisibleForTesting @@ -38,13 +51,18 @@ fun RestrictedSwitchPreference( internal fun RestrictedSwitchPreference( model: SwitchPreferenceModel, restrictions: Restrictions, + ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null, restrictionsProviderFactory: RestrictionsProviderFactory, ) { if (restrictions.isEmpty()) { SwitchPreference(model) return } - restrictionsProviderFactory.RestrictedSwitchWrapper(model, restrictions) { + restrictionsProviderFactory.RestrictedSwitchWrapper( + model = model, + restrictions = restrictions, + ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo, + ) { SwitchPreference(it) } } diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt index fb23637a9f4c..0bb92ce72595 100644 --- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt @@ -42,25 +42,28 @@ internal class RestrictedSwitchPreferenceModel( context: Context, model: SwitchPreferenceModel, private val restrictedMode: RestrictedMode?, + private val ifBlockedByAdminOverrideCheckedValueTo: Boolean?, ) : SwitchPreferenceModel { override val title = model.title - override val summary = getSummary( - context = context, - restrictedModeSupplier = { restrictedMode }, - summaryIfNoRestricted = model.summary, - checked = model.checked, - ) + override val checked = + when (restrictedMode) { + null -> ({ null }) + is NoRestricted -> model.checked + is BaseUserRestricted -> ({ false }) + is BlockedByAdmin -> ({ ifBlockedByAdminOverrideCheckedValueTo ?: model.checked() }) + is BlockedByEcm -> model.checked + } - override val icon = model.icon + override val summary = + getSummary( + context = context, + restrictedModeSupplier = { restrictedMode }, + summaryIfNoRestricted = model.summary, + checkedIfNoRestricted = checked, + ) - override val checked = when (restrictedMode) { - null -> ({ null }) - is NoRestricted -> model.checked - is BaseUserRestricted -> ({ false }) - is BlockedByAdmin -> model.checked - is BlockedByEcm -> model.checked - } + override val icon = model.icon override val changeable = restrictedMode.restrictEnabled(model.changeable) @@ -112,12 +115,20 @@ internal class RestrictedSwitchPreferenceModel( fun RestrictedSwitchWrapper( model: SwitchPreferenceModel, restrictedMode: RestrictedMode?, + ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null, content: @Composable (SwitchPreferenceModel) -> Unit, ) { val context = LocalContext.current - val restrictedSwitchPreferenceModel = remember(restrictedMode, model) { - RestrictedSwitchPreferenceModel(context, model, restrictedMode) - } + val restrictedSwitchPreferenceModel = + remember(restrictedMode, model) { + RestrictedSwitchPreferenceModel( + context = context, + model = model, + restrictedMode = restrictedMode, + ifBlockedByAdminOverrideCheckedValueTo = + ifBlockedByAdminOverrideCheckedValueTo, + ) + } restrictedSwitchPreferenceModel.RestrictionWrapper { content(restrictedSwitchPreferenceModel) } @@ -127,23 +138,31 @@ internal class RestrictedSwitchPreferenceModel( fun RestrictionsProviderFactory.RestrictedSwitchWrapper( model: SwitchPreferenceModel, restrictions: Restrictions, + ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null, content: @Composable (SwitchPreferenceModel) -> Unit, ) { - RestrictedSwitchWrapper(model, rememberRestrictedMode(restrictions).value, content) + RestrictedSwitchWrapper( + model = model, + restrictedMode = rememberRestrictedMode(restrictions).value, + ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo, + content = content, + ) } fun getSummary( context: Context, - restrictedModeSupplier: () -> RestrictedMode?, summaryIfNoRestricted: () -> String, - checked: () -> Boolean?, + checkedIfNoRestricted: () -> Boolean?, + checkedIfBlockedByAdmin: Boolean? = null, + restrictedModeSupplier: () -> RestrictedMode?, ): () -> String = { when (val restrictedMode = restrictedModeSupplier()) { is NoRestricted -> summaryIfNoRestricted() is BaseUserRestricted -> context.getString(com.android.settingslib.R.string.disabled) - is BlockedByAdmin -> restrictedMode.getSummary(checked()) + is BlockedByAdmin -> + restrictedMode.getSummary(checkedIfBlockedByAdmin ?: checkedIfNoRestricted()) is BlockedByEcm -> context.getString(com.android.settingslib.R.string.disabled) diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt index bf0ad0b29072..e73611510f6b 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt @@ -26,9 +26,11 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.RestrictedLockUtils import com.android.settingslib.spa.testutils.FakeNavControllerWrapper import com.android.settingslib.spaprivileged.R import com.android.settingslib.spaprivileged.framework.compose.getPlaceholder +import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdminImpl import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsProvider import com.android.settingslib.spaprivileged.tests.testutils.TestAppRecord @@ -97,6 +99,26 @@ class TogglePermissionAppListPageTest { } @Test + fun summary_whenAllowedButAdminOverrideToNotAllowed() { + fakeRestrictionsProvider.restrictedMode = + BlockedByAdminImpl(context = context, enforcedAdmin = ENFORCED_ADMIN) + val listModel = + TestTogglePermissionAppListModel( + isAllowed = true, + switchifBlockedByAdminOverrideCheckedValueTo = false, + ) + + val summary = getSummary(listModel) + + assertThat(summary) + .isEqualTo( + context.getString( + com.android.settingslib.widget.restricted.R.string.disabled_by_admin + ) + ) + } + + @Test fun appListItem_onClick_navigate() { val listModel = TestTogglePermissionAppListModel() composeTestRule.setContent { @@ -162,8 +184,9 @@ class TogglePermissionAppListPageTest { const val PACKAGE_NAME = "package.name" const val LABEL = "Label" const val SUMMARY = "Summary" - val APP = ApplicationInfo().apply { - packageName = PACKAGE_NAME - } + val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME } + const val RESTRICTION = "restriction" + val ENFORCED_ADMIN: RestrictedLockUtils.EnforcedAdmin = + RestrictedLockUtils.EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(RESTRICTION) } } diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt index b88d1c5760a6..1fd7ecf3cf40 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt @@ -121,7 +121,7 @@ class RestrictedSwitchPreferenceTest { } @Test - fun whenBlockedByAdmin_disabled() { + fun whenBlockedByAdmin_notOverrideChecked() { val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin @@ -133,6 +133,18 @@ class RestrictedSwitchPreferenceTest { } @Test + fun whenBlockedByAdmin_overrideCheckedToFalse() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions, ifBlockedByAdminOverrideCheckedValueTo = false) + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() + composeTestRule.onNodeWithText(FakeBlockedByAdmin.SUMMARY).assertIsDisplayed() + composeTestRule.onNode(isOff()).assertIsDisplayed() + } + + @Test fun whenBlockedByAdmin_click() { val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin @@ -166,9 +178,16 @@ class RestrictedSwitchPreferenceTest { assertThat(fakeBlockedByEcm.showRestrictedSettingsDetailsIsCalled).isTrue() } - private fun setContent(restrictions: Restrictions) { + private fun setContent( + restrictions: Restrictions, + ifBlockedByAdminOverrideCheckedValueTo: Boolean? = null, + ) { composeTestRule.setContent { - RestrictedSwitchPreference(switchPreferenceModel, restrictions) { _, _ -> + RestrictedSwitchPreference( + model = switchPreferenceModel, + restrictions = restrictions, + ifBlockedByAdminOverrideCheckedValueTo = ifBlockedByAdminOverrideCheckedValueTo, + ) { _, _ -> fakeRestrictionsProvider } } diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt index 17903130a8a5..000743e7ef8a 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/TestTogglePermissionAppListModel.kt @@ -28,6 +28,7 @@ import kotlinx.coroutines.flow.Flow class TestTogglePermissionAppListModel( isAllowed: Boolean? = null, private val isChangeable: Boolean = false, + override val switchifBlockedByAdminOverrideCheckedValueTo: Boolean? = null, ) : TogglePermissionAppListModel<TestAppRecord> { override val pageTitleResId = R.string.test_permission_title override val switchTitleResId = R.string.test_permission_switch_title |