summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hani Kazmi <hanikazmi@google.com> 2023-12-07 23:35:26 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-12-07 23:35:26 +0000
commitfce39f1443b1348c5c36951d165f56f99ca1fee4 (patch)
tree1f6155b6f6adda69ee4dcc1951da54769d3d3eb9
parent08f3d0adacbec8ea11f0d678fcab121f95ec90d7 (diff)
parentc30ecdc7437d83abb0e0bf7990e20d7eba15425a (diff)
Merge "Update Special App Access Compose Components for ECM" into main
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt16
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt20
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt3
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt8
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt3
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt11
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreference.kt2
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt49
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java48
10 files changed, 144 insertions, 18 deletions
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt
index 3acc9ad83d2c..b6d92422c333 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt
@@ -18,6 +18,7 @@ package com.android.settingslib.spaprivileged.model.enterprise
import android.app.admin.DevicePolicyResources.Strings.Settings
import android.content.Context
+import android.content.Intent
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.widget.restricted.R
@@ -32,6 +33,11 @@ interface BlockedByAdmin : RestrictedMode {
fun sendShowAdminSupportDetailsIntent()
}
+interface BlockedByEcm : RestrictedMode {
+ fun showRestrictedSettingsDetails()
+}
+
+
internal data class BlockedByAdminImpl(
private val context: Context,
private val enforcedAdmin: RestrictedLockUtils.EnforcedAdmin,
@@ -55,3 +61,13 @@ internal data class BlockedByAdminImpl(
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, enforcedAdmin)
}
}
+
+internal data class BlockedByEcmImpl(
+ private val context: Context,
+ private val intent: Intent,
+) : BlockedByEcm {
+
+ override fun showRestrictedSettingsDetails() {
+ context.startActivity(intent)
+ }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt
index 550966beb0b8..9432d5995151 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt
@@ -29,10 +29,20 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
+data class EnhancedConfirmation(
+ val key: String,
+ val uid: Int,
+ val packageName: String,
+)
data class Restrictions(
val userId: Int = UserHandle.myUserId(),
val keys: List<String>,
-)
+ val enhancedConfirmation: EnhancedConfirmation? = null,
+) {
+ fun isEmpty(): Boolean {
+ return keys.isEmpty() && enhancedConfirmation == null
+ }
+}
interface RestrictionsProvider {
@Composable
@@ -77,6 +87,14 @@ internal class RestrictionsProviderImpl(
.checkIfRestrictionEnforced(context, key, restrictions.userId)
?.let { return BlockedByAdminImpl(context = context, enforcedAdmin = it) }
}
+
+ restrictions.enhancedConfirmation?.let { ec ->
+ RestrictedLockUtilsInternal
+ .checkIfRequiresEnhancedConfirmation(context, ec.key,
+ ec.uid, ec.packageName)
+ ?.let { intent -> return BlockedByEcmImpl(context = context, intent = intent) }
+ }
+
return NoRestricted
}
}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
index 06b3eabfad26..25c3bc541249 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppOpPermissionAppList.kt
@@ -47,6 +47,9 @@ abstract class AppOpPermissionListModel(
abstract val appOp: Int
abstract val permission: String
+ override val enhancedConfirmationKey: String?
+ get() = AppOpsManager.opToPublicName(appOp)
+
/**
* When set, specifies the broader permission who trumps the [permission].
*
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 565543614866..1c830c1c5b06 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,6 +41,7 @@ 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
@@ -154,7 +155,12 @@ internal fun <T : AppRecord> TogglePermissionAppListModel<T>.TogglePermissionApp
override val changeable = { isChangeable }
override val onCheckedChange: (Boolean) -> Unit = { setAllowed(record, it) }
}
- val restrictions = Restrictions(userId, switchRestrictionKeys)
+ val restrictions = Restrictions(userId = userId,
+ keys = switchRestrictionKeys,
+ enhancedConfirmation = enhancedConfirmationKey?.let { EnhancedConfirmation(
+ key = it,
+ uid = checkNotNull(applicationInfo).uid,
+ packageName = packageName) })
RestrictedSwitchPreference(switchModel, restrictions, restrictionsProviderFactory)
}
}
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 8704f20f5c4a..916d83af3f8f 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
@@ -36,6 +36,9 @@ interface TogglePermissionAppListModel<T : AppRecord> {
val switchRestrictionKeys: List<String>
get() = emptyList()
+ val enhancedConfirmationKey: String?
+ get() = null
+
/**
* Loads the extra info for the App List, and generates the [AppRecord] List.
*
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 36c91f463efe..4b474379c54b 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
@@ -41,6 +41,7 @@ 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
@@ -149,11 +150,17 @@ internal class TogglePermissionInternalAppListModel<T : AppRecord>(
@Composable
fun getSummary(record: T): () -> String {
- val restrictions = remember(record.app.userId) {
+ val restrictions = remember(record.app.userId,
+ record.app.uid, record.app.packageName) {
Restrictions(
userId = record.app.userId,
keys = listModel.switchRestrictionKeys,
- )
+ enhancedConfirmation = listModel.enhancedConfirmationKey?.let {
+ EnhancedConfirmation(
+ key = it,
+ uid = record.app.uid,
+ packageName = record.app.packageName)
+ })
}
val restrictedMode by restrictionsProviderFactory.rememberRestrictedMode(restrictions)
val allowed = listModel.isAllowed(record)
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 d5c5574a0450..cd720252e485 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
@@ -40,7 +40,7 @@ internal fun RestrictedSwitchPreference(
restrictions: Restrictions,
restrictionsProviderFactory: RestrictionsProviderFactory,
) {
- if (restrictions.keys.isEmpty()) {
+ if (restrictions.isEmpty()) {
SwitchPreference(model)
return
}
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 fa44ecb92ed5..aba3460fc1b9 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
@@ -31,6 +31,7 @@ import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spaprivileged.framework.compose.getPlaceholder
import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted
import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin
+import com.android.settingslib.spaprivileged.model.enterprise.BlockedByEcm
import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted
import com.android.settingslib.spaprivileged.model.enterprise.RestrictedMode
import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
@@ -56,6 +57,7 @@ internal class RestrictedSwitchPreferenceModel(
is NoRestricted -> model.checked
is BaseUserRestricted -> ({ false })
is BlockedByAdmin -> model.checked
+ is BlockedByEcm -> model.checked
}
override val changeable = if (restrictedMode is NoRestricted) model.changeable else ({ false })
@@ -68,24 +70,42 @@ internal class RestrictedSwitchPreferenceModel(
is BaseUserRestricted -> model.onCheckedChange
// Pass null since semantics ToggleableState is provided in RestrictionWrapper.
is BlockedByAdmin -> null
+ is BlockedByEcm -> null
}
@Composable
fun RestrictionWrapper(content: @Composable () -> Unit) {
- if (restrictedMode !is BlockedByAdmin) {
- content()
- return
+ when (restrictedMode) {
+ is BlockedByAdmin -> {
+ Box(
+ Modifier
+ .clickable(
+ role = Role.Switch,
+ onClick = { restrictedMode.sendShowAdminSupportDetailsIntent() },
+ )
+ .semantics {
+ this.toggleableState = ToggleableState(checked())
+ },
+ ) { content() }
+ }
+
+ is BlockedByEcm -> {
+ Box(
+ Modifier
+ .clickable(
+ role = Role.Switch,
+ onClick = { restrictedMode.showRestrictedSettingsDetails() },
+ )
+ .semantics {
+ this.toggleableState = ToggleableState(checked())
+ },
+ ) { content() }
+ }
+
+ else -> {
+ content()
+ }
}
- Box(
- Modifier
- .clickable(
- role = Role.Switch,
- onClick = { restrictedMode.sendShowAdminSupportDetailsIntent() },
- )
- .semantics {
- this.toggleableState = ToggleableState(checked())
- },
- ) { content() }
}
private fun ToggleableState(value: Boolean?) = when (value) {
@@ -123,6 +143,9 @@ internal class RestrictedSwitchPreferenceModel(
context.getString(com.android.settingslib.R.string.disabled)
is BlockedByAdmin -> restrictedMode.getSummary(checked())
+ is BlockedByEcm ->
+ context.getString(com.android.settingslib.R.string.disabled)
+
null -> context.getPlaceholder()
}
}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt
index f9abefc11e24..977615b55a6a 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.Composable
import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope
import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted
import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin
+import com.android.settingslib.spaprivileged.model.enterprise.BlockedByEcm
import com.android.settingslib.spaprivileged.model.enterprise.Restrictions
import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderFactory
import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl
@@ -47,6 +48,7 @@ internal fun MoreOptionsScope.RestrictedMenuItemImpl(
MenuItem(text = text, enabled = restrictedMode !== BaseUserRestricted) {
when (restrictedMode) {
is BlockedByAdmin -> restrictedMode.sendShowAdminSupportDetailsIntent()
+ is BlockedByEcm -> restrictedMode.showRestrictedSettingsDetails()
else -> onClick()
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index e77964c6fa0c..4454b710b7e4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -22,13 +22,16 @@ import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AF
import static com.android.settingslib.Utils.getColorAttrDefaultColor;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppGlobals;
+import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
@@ -39,10 +42,12 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager.EnforcingUser;
+import android.provider.Settings;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.text.style.ImageSpan;
+import android.util.ArraySet;
import android.util.Log;
import android.view.MenuItem;
import android.widget.TextView;
@@ -53,6 +58,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import java.util.List;
+import java.util.Set;
/**
* Utility class to host methods usable in adding a restricted padlock icon and showing admin
@@ -62,6 +68,16 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
private static final String LOG_TAG = "RestrictedLockUtils";
private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+ private static final Set<String> ECM_KEYS = new ArraySet<>();
+
+ static {
+ if (android.security.Flags.extendEcmToAllSettings()) {
+ ECM_KEYS.add(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW);
+ ECM_KEYS.add(AppOpsManager.OPSTR_GET_USAGE_STATS);
+ ECM_KEYS.add(AppOpsManager.OPSTR_LOADER_USAGE_STATS);
+ ECM_KEYS.add(Manifest.permission.BIND_DEVICE_ADMIN);
+ }
+ }
/**
* @return drawables for displaying with settings that are locked by a device admin.
@@ -81,6 +97,38 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
}
/**
+ * Checks if a given permission requires additional confirmation for the given package
+ *
+ * @return An intent to show the user if additional confirmation is required, null otherwise
+ */
+ @Nullable
+ public static Intent checkIfRequiresEnhancedConfirmation(@NonNull Context context,
+ @NonNull String restriction,
+ int uid,
+ @Nullable String packageName) {
+ // TODO(b/297372999): Replace with call to mainline module once ready
+
+ if (!ECM_KEYS.contains(restriction)) {
+ return null;
+ }
+
+ final AppOpsManager appOps = (AppOpsManager) context
+ .getSystemService(Context.APP_OPS_SERVICE);
+ final int mode = appOps.noteOpNoThrow(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
+ uid, packageName, null, null);
+ final boolean ecmEnabled = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_enhancedConfirmationModeEnabled);
+ if (ecmEnabled && mode != AppOpsManager.MODE_ALLOWED) {
+ final Intent intent = new Intent(Settings.ACTION_SHOW_RESTRICTED_SETTING_DIALOG);
+ intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
+ intent.putExtra(Intent.EXTRA_UID, uid);
+ return intent;
+ }
+
+ return null;
+ }
+
+ /**
* Checks if a restriction is enforced on a user and returns the enforced admin and
* admin userId.
*