summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Azhara Assanova <azharaa@google.com> 2024-11-27 10:45:33 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-11-27 10:45:33 +0000
commit946200b9f8a18e765649013139dd0e93a8dc270e (patch)
treeec52d38b4aa0a41a019bb18a4191bdee1fb32353
parenta2a4d00d3f59e0ced82f4a3a2b2a26a2cfa0658a (diff)
parenta30fb7eaa3eeb5099c806f0f37c8b950ac7e7c2d (diff)
Merge changes from topic "aapm-support-dialog-settings-strings" into main
* changes: [AAPM] Update SPA settings to show advanced protection strings [AAPM] Add DevicePolicyManager#getEnforcingAdmin for settings pages
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java30
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl5
-rw-r--r--core/java/android/app/admin/UnknownAuthority.java35
-rw-r--r--core/java/android/security/advancedprotection/AdvancedProtectionManager.java25
-rw-r--r--packages/SettingsLib/RestrictedLockUtils/res/values/strings.xml11
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt19
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedMode.kt12
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictionsProvider.kt6
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt145
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPageTest.kt102
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt11
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java29
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java41
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java27
-rw-r--r--services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java1
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java99
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java4
17 files changed, 549 insertions, 53 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 74d729857cc8..8372078b46a5 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -12486,6 +12486,36 @@ public class DevicePolicyManager {
}
/**
+ * Returns the {@link EnforcingAdmin} who have set this policy.
+ *
+ * <p>Important: this API is a temporary solution, hence should be kept hidden. That is because
+ * the string argument can't define policies with arguments.
+ *
+ * <p>Note that for {@link #POLICY_SUSPEND_PACKAGES} it returns the PO or DO to keep the
+ * behavior the same as before the bug fix for b/192245204.
+ *
+ * <p>This API is only callable by the system UID
+ *
+ * @param userId The user for whom to retrieve the information.
+ * @param identifier The policy enforced by admins. It could be any user restriction or
+ * policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA} and
+ * {@link DevicePolicyManager#POLICY_DISABLE_SCREEN_CAPTURE}. This also works
+ * for {@link DevicePolicyIdentifiers#MEMORY_TAGGING_POLICY}.
+ *
+ * @hide
+ */
+ public @Nullable EnforcingAdmin getEnforcingAdmin(int userId, String identifier) {
+ if (mService != null) {
+ try {
+ return mService.getEnforcingAdmin(userId, identifier);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns the list of {@link EnforcingAdmin}s who have set this restriction.
*
* <p>Note that for {@link #POLICY_SUSPEND_PACKAGES} it returns the PO or DO to keep the
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index e7be822d52d3..03a9f9955086 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -279,8 +279,9 @@ interface IDevicePolicyManager {
boolean isNotificationListenerServicePermitted(in String packageName, int userId);
Intent createAdminSupportIntent(in String restriction);
- Bundle getEnforcingAdminAndUserDetails(int userId,String restriction);
- List<EnforcingAdmin> getEnforcingAdminsForRestriction(int userId,String restriction);
+ Bundle getEnforcingAdminAndUserDetails(int userId, String restriction);
+ EnforcingAdmin getEnforcingAdmin(int userId, String identifier);
+ List<EnforcingAdmin> getEnforcingAdminsForRestriction(int userId, String restriction);
boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden, boolean parent);
boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean parent);
diff --git a/core/java/android/app/admin/UnknownAuthority.java b/core/java/android/app/admin/UnknownAuthority.java
index fdad898b7bd9..82dcf7e1a115 100644
--- a/core/java/android/app/admin/UnknownAuthority.java
+++ b/core/java/android/app/admin/UnknownAuthority.java
@@ -22,6 +22,8 @@ import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.os.Parcel;
+import java.util.Objects;
+
/**
* Class used to identify a default value for the authority of the {@link EnforcingAdmin} setting
* a policy, meaning it is not one of the other known subclasses of {@link Authority}, this would be
@@ -31,6 +33,7 @@ import android.os.Parcel;
*/
@SystemApi
public final class UnknownAuthority extends Authority {
+ private final String mName;
/**
* Object representing an unknown authority.
@@ -45,22 +48,40 @@ public final class UnknownAuthority extends Authority {
* Creates an authority that represents an admin that can set a policy but
* doesn't have a known authority (e.g. a system components).
*/
- public UnknownAuthority() {}
+ public UnknownAuthority() {
+ mName = null;
+ }
+
+ /** @hide */
+ public UnknownAuthority(String name) {
+ mName = name;
+ }
+
+ private UnknownAuthority(Parcel source) {
+ this(source.readString8());
+ }
+
+ /** @hide */
+ public String getName() {
+ return mName;
+ }
@Override
public String toString() {
- return "DefaultAuthority {}";
+ return "DefaultAuthority {" + mName + "}";
}
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
- return o != null && getClass() == o.getClass();
+ if (o != null && getClass() == o.getClass()) return false;
+ UnknownAuthority other = (UnknownAuthority) o;
+ return Objects.equals(mName, other.mName);
}
@Override
public int hashCode() {
- return 0;
+ return mName.hashCode();
}
@Override
@@ -69,14 +90,16 @@ public final class UnknownAuthority extends Authority {
}
@Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {}
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString8(mName);
+ }
@NonNull
public static final Creator<UnknownAuthority> CREATOR =
new Creator<UnknownAuthority>() {
@Override
public UnknownAuthority createFromParcel(Parcel source) {
- return UNKNOWN_AUTHORITY;
+ return new UnknownAuthority(source);
}
@Override
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index 0302fafd2f6c..59628e8e69d7 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -16,7 +16,10 @@
package android.security.advancedprotection;
+import static android.app.admin.DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.os.UserManager.DISALLOW_CELLULAR_2G;
+import static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY;
import android.Manifest;
import android.annotation.CallbackExecutor;
@@ -343,6 +346,28 @@ public final class AdvancedProtectionManager {
return intent;
}
+ /** @hide */
+ public @NonNull Intent createSupportIntentForPolicyIdentifierOrRestriction(
+ @NonNull String identifier, @Nullable @SupportDialogType String type) {
+ Objects.requireNonNull(identifier);
+ if (type != null && !ALL_SUPPORT_DIALOG_TYPES.contains(type)) {
+ throw new IllegalArgumentException(type + " is not a valid type. See"
+ + " SUPPORT_DIALOG_TYPE_* APIs.");
+ }
+ final String featureId;
+ if (DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY.equals(identifier)) {
+ featureId = FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
+ } else if (DISALLOW_CELLULAR_2G.equals(identifier)) {
+ featureId = FEATURE_ID_DISALLOW_CELLULAR_2G;
+ } else if (android.app.admin.flags.Flags.setMtePolicyCoexistence() && MEMORY_TAGGING_POLICY
+ .equals(identifier)) {
+ featureId = FEATURE_ID_ENABLE_MTE;
+ } else {
+ throw new UnsupportedOperationException("Unsupported identifier: " + identifier);
+ }
+ return createSupportIntent(featureId, type);
+ }
+
/**
* A callback class for monitoring changes to Advanced Protection state
*
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values/strings.xml
index 7e4460ba815d..75809730a514 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values/strings.xml
@@ -17,9 +17,12 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Summary for switch preference to denote it is switched on [CHAR LIMIT=50] -->
+ <!-- Summary for switch preference to denote it is switched on by an admin [CHAR LIMIT=50] -->
<string name="enabled_by_admin">Enabled by admin</string>
- <!-- Summary for switch preference to denote it is switched off [CHAR LIMIT=50] -->
+ <!-- Summary for switch preference to denote it is switched off by an admin [CHAR LIMIT=50] -->
<string name="disabled_by_admin">Disabled by admin</string>
-
-</resources> \ No newline at end of file
+ <!-- Summary for switch preference to denote it is switched on by Advanced protection [CHAR LIMIT=50] -->
+ <string name="enabled_by_advanced_protection">Enabled by Advanced Protection</string>
+ <!-- Summary for switch preference to denote it is switched off by Advanced protection [CHAR LIMIT=50] -->
+ <string name="disabled_by_advanced_protection">Disabled by Advanced Protection</string>
+</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt
index 5baf7be98666..b5a6ffa03317 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/enterprise/EnterpriseRepository.kt
@@ -22,10 +22,14 @@ import android.app.admin.DevicePolicyResources.Strings.Settings.WORK_CATEGORY_HE
import android.content.Context
import android.content.pm.UserInfo
import com.android.settingslib.R
+import com.android.settingslib.RestrictedLockUtils
+import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
interface IEnterpriseRepository {
fun getEnterpriseString(updatableStringId: String, resId: Int): String
+ fun getAdminSummaryString(advancedProtectionStringId: Int, updatableStringId: String,
+ resId: Int, enforcedAdmin: RestrictedLockUtils.EnforcedAdmin?, userId: Int): String
}
class EnterpriseRepository(private val context: Context) : IEnterpriseRepository {
@@ -34,6 +38,21 @@ class EnterpriseRepository(private val context: Context) : IEnterpriseRepository
override fun getEnterpriseString(updatableStringId: String, resId: Int): String =
checkNotNull(resources.getString(updatableStringId) { context.getString(resId) })
+ override fun getAdminSummaryString(
+ advancedProtectionStringId: Int,
+ updatableStringId: String,
+ resId: Int,
+ enforcedAdmin: RestrictedLockUtils.EnforcedAdmin?,
+ userId: Int
+ ): String {
+ return if (RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(context,
+ enforcedAdmin?.enforcedRestriction, userId)) {
+ context.getString(advancedProtectionStringId)
+ } else {
+ getEnterpriseString(updatableStringId, resId)
+ }
+ }
+
fun getProfileTitle(userInfo: UserInfo): String = if (userInfo.isManagedProfile) {
getEnterpriseString(WORK_CATEGORY_HEADER, R.string.category_work)
} else if (userInfo.isPrivateProfile) {
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 b6d92422c333..a140eb8424a8 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
@@ -37,21 +37,27 @@ interface BlockedByEcm : RestrictedMode {
fun showRestrictedSettingsDetails()
}
-
internal data class BlockedByAdminImpl(
private val context: Context,
private val enforcedAdmin: RestrictedLockUtils.EnforcedAdmin,
+ private val userId: Int,
private val enterpriseRepository: IEnterpriseRepository = EnterpriseRepository(context),
) : BlockedByAdmin {
override fun getSummary(checked: Boolean?) = when (checked) {
- true -> enterpriseRepository.getEnterpriseString(
+ true -> enterpriseRepository.getAdminSummaryString(
+ advancedProtectionStringId = R.string.enabled_by_advanced_protection,
updatableStringId = Settings.ENABLED_BY_ADMIN_SWITCH_SUMMARY,
resId = R.string.enabled_by_admin,
+ enforcedAdmin = enforcedAdmin,
+ userId = userId,
)
- false -> enterpriseRepository.getEnterpriseString(
+ false -> enterpriseRepository.getAdminSummaryString(
+ advancedProtectionStringId = R.string.disabled_by_advanced_protection,
updatableStringId = Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY,
resId = R.string.disabled_by_admin,
+ enforcedAdmin = enforcedAdmin,
+ userId = userId,
)
else -> ""
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 6b1893c73b3f..3309faaa8db2 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
@@ -84,7 +84,11 @@ internal class RestrictionsProviderImpl(
for (key in restrictions.keys) {
RestrictedLockUtilsInternal
.checkIfRestrictionEnforced(context, key, restrictions.userId)
- ?.let { return BlockedByAdminImpl(context = context, enforcedAdmin = it) }
+ ?.let { return BlockedByAdminImpl(
+ context = context,
+ enforcedAdmin = it,
+ userId = restrictions.userId
+ ) }
}
restrictions.enhancedConfirmation?.let { ec ->
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt
index 8fd16b37bfeb..f3245c9085e7 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/enterprise/RestrictedModeTest.kt
@@ -16,19 +16,49 @@
package com.android.settingslib.spaprivileged.model.enterprise
+import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyResources.Strings.Settings
+import android.app.admin.EnforcingAdmin
import android.content.Context
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.security.Flags
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settingslib.RestrictedLockUtils
+import com.android.settingslib.RestrictedLockUtilsInternal
+import com.android.settingslib.spaprivileged.framework.common.devicePolicyManager
+import com.android.settingslib.spaprivileged.tests.testutils.getEnforcingAdminAdvancedProtection
+import com.android.settingslib.spaprivileged.tests.testutils.getEnforcingAdminNotAdvancedProtection
+import com.android.settingslib.widget.restricted.R
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Spy
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class RestrictedModeTest {
+ @Rule
+ @JvmField
+ val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
+ @get:Rule
+ val mockito: MockitoRule = MockitoJUnit.rule()
+
+ @Spy
private val context: Context = ApplicationProvider.getApplicationContext()
+ @Mock
+ private lateinit var devicePolicyManager: DevicePolicyManager
+
private val fakeEnterpriseRepository = object : IEnterpriseRepository {
override fun getEnterpriseString(updatableStringId: String, resId: Int): String =
when (updatableStringId) {
@@ -36,20 +66,123 @@ class RestrictedModeTest {
Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY -> DISABLED_BY_ADMIN
else -> ""
}
+
+ override fun getAdminSummaryString(
+ advancedProtectionStringId: Int,
+ updatableStringId: String,
+ resId: Int,
+ enforcedAdmin: RestrictedLockUtils.EnforcedAdmin?,
+ userId: Int
+ ): String {
+ if (RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(context,
+ RESTRICTION, userId)) {
+ return when (advancedProtectionStringId) {
+ R.string.enabled_by_advanced_protection -> ENABLED_BY_ADVANCED_PROTECTION
+ R.string.disabled_by_advanced_protection -> DISABLED_BY_ADVANCED_PROTECTION
+ else -> ""
+ }
+ }
+ return getEnterpriseString(updatableStringId, resId)
+ }
}
+ @Before
+ fun setUp() {
+ whenever(context.devicePolicyManager).thenReturn(devicePolicyManager)
+ }
+
+ @RequiresFlagsDisabled(Flags.FLAG_AAPM_API)
@Test
fun blockedByAdmin_getSummaryWhenChecked() {
- val blockedByAdmin = BlockedByAdminImpl(context, ENFORCED_ADMIN, fakeEnterpriseRepository)
+ val blockedByAdmin = BlockedByAdminImpl(context, ENFORCED_ADMIN, USER_ID,
+ fakeEnterpriseRepository)
val summary = blockedByAdmin.getSummary(true)
assertThat(summary).isEqualTo(ENABLED_BY_ADMIN)
}
+ @RequiresFlagsDisabled(Flags.FLAG_AAPM_API)
@Test
fun blockedByAdmin_getSummaryNotWhenChecked() {
- val blockedByAdmin = BlockedByAdminImpl(context, ENFORCED_ADMIN, fakeEnterpriseRepository)
+ val blockedByAdmin = BlockedByAdminImpl(context, ENFORCED_ADMIN, USER_ID,
+ fakeEnterpriseRepository)
+
+ val summary = blockedByAdmin.getSummary(false)
+
+ assertThat(summary).isEqualTo(DISABLED_BY_ADMIN)
+ }
+
+ @RequiresFlagsEnabled(Flags.FLAG_AAPM_API)
+ @Test
+ fun blockedByAdmin_disabledByAdvancedProtection_getSummaryWhenChecked() {
+ val blockedByAdmin =
+ BlockedByAdminImpl(
+ context = context,
+ enforcedAdmin = ENFORCED_ADMIN,
+ enterpriseRepository = fakeEnterpriseRepository,
+ userId = USER_ID,
+ )
+
+ whenever(devicePolicyManager.getEnforcingAdmin(USER_ID, RESTRICTION))
+ .thenReturn(ENFORCING_ADMIN_ADVANCED_PROTECTION)
+
+ val summary = blockedByAdmin.getSummary(true)
+
+ assertThat(summary).isEqualTo(ENABLED_BY_ADVANCED_PROTECTION)
+ }
+
+ @RequiresFlagsEnabled(Flags.FLAG_AAPM_API)
+ @Test
+ fun blockedByAdmin_disabledByAdvancedProtection_getSummaryWhenNotChecked() {
+ val blockedByAdmin =
+ BlockedByAdminImpl(
+ context = context,
+ enforcedAdmin = ENFORCED_ADMIN,
+ enterpriseRepository = fakeEnterpriseRepository,
+ userId = USER_ID,
+ )
+
+ whenever(devicePolicyManager.getEnforcingAdmin(USER_ID, RESTRICTION))
+ .thenReturn(ENFORCING_ADMIN_ADVANCED_PROTECTION)
+
+ val summary = blockedByAdmin.getSummary(false)
+
+ assertThat(summary).isEqualTo(DISABLED_BY_ADVANCED_PROTECTION)
+ }
+
+ @RequiresFlagsEnabled(Flags.FLAG_AAPM_API)
+ @Test
+ fun blockedByAdmin_notDisabledByAdvancedProtection_getSummaryWhenChecked() {
+ val blockedByAdmin =
+ BlockedByAdminImpl(
+ context = context,
+ enforcedAdmin = ENFORCED_ADMIN,
+ enterpriseRepository = fakeEnterpriseRepository,
+ userId = USER_ID,
+ )
+
+ whenever(devicePolicyManager.getEnforcingAdmin(USER_ID, RESTRICTION))
+ .thenReturn(ENFORCING_ADMIN_NOT_ADVANCED_PROTECTION)
+
+ val summary = blockedByAdmin.getSummary(true)
+
+ assertThat(summary).isEqualTo(ENABLED_BY_ADMIN)
+ }
+
+ @RequiresFlagsEnabled(Flags.FLAG_AAPM_API)
+ @Test
+ fun blockedByAdmin_notDisabledByAdvancedProtection_getSummaryWhenNotChecked() {
+ val blockedByAdmin =
+ BlockedByAdminImpl(
+ context = context,
+ enforcedAdmin = ENFORCED_ADMIN,
+ enterpriseRepository = fakeEnterpriseRepository,
+ userId = USER_ID,
+ )
+
+ whenever(devicePolicyManager.getEnforcingAdmin(USER_ID, RESTRICTION))
+ .thenReturn(ENFORCING_ADMIN_NOT_ADVANCED_PROTECTION)
val summary = blockedByAdmin.getSummary(false)
@@ -57,11 +190,19 @@ class RestrictedModeTest {
}
private companion object {
+ const val PACKAGE_NAME = "package.name"
const val RESTRICTION = "restriction"
+ const val USER_ID = 0
val ENFORCED_ADMIN: RestrictedLockUtils.EnforcedAdmin =
RestrictedLockUtils.EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(RESTRICTION)
+ val ENFORCING_ADMIN_ADVANCED_PROTECTION: EnforcingAdmin =
+ getEnforcingAdminAdvancedProtection(PACKAGE_NAME, USER_ID)
+ val ENFORCING_ADMIN_NOT_ADVANCED_PROTECTION: EnforcingAdmin =
+ getEnforcingAdminNotAdvancedProtection(PACKAGE_NAME, USER_ID)
const val ENABLED_BY_ADMIN = "Enabled by admin"
const val DISABLED_BY_ADMIN = "Disabled by admin"
+ const val ENABLED_BY_ADVANCED_PROTECTION = "Enabled by advanced protection"
+ const val DISABLED_BY_ADVANCED_PROTECTION = "Disabled by advanced protection"
}
}
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 e73611510f6b..79085af63c6d 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
@@ -16,8 +16,17 @@
package com.android.settingslib.spaprivileged.template.app
+import android.app.admin.DevicePolicyManager
+import android.app.admin.DevicePolicyResources.Strings.Settings
+import android.app.admin.DevicePolicyResourcesManager
+import android.app.admin.EnforcingAdmin
import android.content.Context
import android.content.pm.ApplicationInfo
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.CheckFlagsRule
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
+import android.security.Flags
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.test.assertIsDisplayed
@@ -29,28 +38,59 @@ 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.common.devicePolicyManager
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
import com.android.settingslib.spaprivileged.tests.testutils.TestTogglePermissionAppListModel
+import com.android.settingslib.spaprivileged.tests.testutils.getEnforcingAdminAdvancedProtection
+import com.android.settingslib.spaprivileged.tests.testutils.getEnforcingAdminNotAdvancedProtection
import com.google.common.truth.Truth.assertThat
+import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Spy
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class)
class TogglePermissionAppListPageTest {
+ @Rule
+ @JvmField
+ val mCheckFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
+
@get:Rule
val composeTestRule = createComposeRule()
+ @get:Rule
+ val mockito: MockitoRule = MockitoJUnit.rule()
+
+ @Mock
+ private lateinit var devicePolicyManager: DevicePolicyManager
+
+ @Mock
+ private lateinit var devicePolicyResourcesManager: DevicePolicyResourcesManager
+
+ @Spy
private val context: Context = ApplicationProvider.getApplicationContext()
private val fakeNavControllerWrapper = FakeNavControllerWrapper()
private val fakeRestrictionsProvider = FakeRestrictionsProvider()
+ @Before
+ fun setUp() {
+ whenever(context.devicePolicyManager).thenReturn(devicePolicyManager)
+ whenever(devicePolicyManager.resources).thenReturn(devicePolicyResourcesManager)
+ }
+
@Test
fun pageTitle() {
val listModel = TestTogglePermissionAppListModel()
@@ -98,10 +138,65 @@ class TogglePermissionAppListPageTest {
assertThat(summary).isEqualTo(context.getPlaceholder())
}
+ @RequiresFlagsDisabled(Flags.FLAG_AAPM_API)
@Test
fun summary_whenAllowedButAdminOverrideToNotAllowed() {
fakeRestrictionsProvider.restrictedMode =
- BlockedByAdminImpl(context = context, enforcedAdmin = ENFORCED_ADMIN)
+ BlockedByAdminImpl(context = context, enforcedAdmin = ENFORCED_ADMIN, userId = USER_ID)
+ 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
+ )
+ )
+ }
+
+ @RequiresFlagsEnabled(Flags.FLAG_AAPM_API)
+ @Test
+ fun summary_disabledByAdvancedProtection_whenAllowedButAdminOverrideToNotAllowed() {
+ whenever(devicePolicyManager.getEnforcingAdmin(USER_ID, RESTRICTION))
+ .thenReturn(ENFORCING_ADMIN_ADVANCED_PROTECTION)
+
+ fakeRestrictionsProvider.restrictedMode =
+ BlockedByAdminImpl(context = context, enforcedAdmin = ENFORCED_ADMIN, userId = USER_ID)
+ 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_advanced_protection
+ )
+ )
+ }
+
+ @RequiresFlagsEnabled(Flags.FLAG_AAPM_API)
+ @Test
+ fun summary_notDisabledByAdvancedProtection_whenAllowedButAdminOverrideToNotAllowed() {
+ val disabledByAdminText = context.getString(
+ com.android.settingslib.widget.restricted.R.string.disabled_by_admin
+ )
+ whenever(devicePolicyManager.getEnforcingAdmin(USER_ID, RESTRICTION))
+ .thenReturn(ENFORCING_ADMIN_NOT_ADVANCED_PROTECTION)
+ whenever(devicePolicyResourcesManager.getString(
+ eq(Settings.DISABLED_BY_ADMIN_SWITCH_SUMMARY), any())).thenReturn(disabledByAdminText)
+
+ fakeRestrictionsProvider.restrictedMode =
+ BlockedByAdminImpl(context = context, enforcedAdmin = ENFORCED_ADMIN, userId = USER_ID)
val listModel =
TestTogglePermissionAppListModel(
isAllowed = true,
@@ -186,7 +281,12 @@ class TogglePermissionAppListPageTest {
const val SUMMARY = "Summary"
val APP = ApplicationInfo().apply { packageName = PACKAGE_NAME }
const val RESTRICTION = "restriction"
+ const val USER_ID = 0
val ENFORCED_ADMIN: RestrictedLockUtils.EnforcedAdmin =
RestrictedLockUtils.EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(RESTRICTION)
+ val ENFORCING_ADMIN_ADVANCED_PROTECTION: EnforcingAdmin =
+ getEnforcingAdminAdvancedProtection(PACKAGE_NAME, USER_ID)
+ val ENFORCING_ADMIN_NOT_ADVANCED_PROTECTION: EnforcingAdmin =
+ getEnforcingAdminNotAdvancedProtection(PACKAGE_NAME, USER_ID)
}
}
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt
index f8ca2a084f14..d5e8d6a5fa13 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt
@@ -16,6 +16,10 @@
package com.android.settingslib.spaprivileged.tests.testutils
+import android.app.admin.EnforcingAdmin
+import android.app.admin.UnknownAuthority
+import android.os.UserHandle
+import android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY
import androidx.compose.runtime.Composable
import com.android.settingslib.spa.framework.compose.stateOf
import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin
@@ -55,3 +59,10 @@ class FakeRestrictionsProvider : RestrictionsProvider {
@Composable
override fun restrictedModeState() = stateOf(restrictedMode)
}
+
+fun getEnforcingAdminAdvancedProtection(packageName: String, userId: Int): EnforcingAdmin =
+ EnforcingAdmin(packageName, UnknownAuthority(ADVANCED_PROTECTION_SYSTEM_ENTITY),
+ UserHandle.of(userId))
+
+fun getEnforcingAdminNotAdvancedProtection(packageName: String, userId: Int): EnforcingAdmin =
+ EnforcingAdmin(packageName, UnknownAuthority.UNKNOWN_AUTHORITY, UserHandle.of(userId))
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index fc163ce79009..4de64769b425 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -27,8 +27,10 @@ import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
-import android.app.ecm.EnhancedConfirmationManager;
+import android.app.admin.EnforcingAdmin;
import android.app.admin.PackagePolicy;
+import android.app.admin.UnknownAuthority;
+import android.app.ecm.EnhancedConfirmationManager;
import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
@@ -43,6 +45,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManager.EnforcingUser;
+import android.security.advancedprotection.AdvancedProtectionManager;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
@@ -202,6 +205,14 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
return null;
}
+ if (android.security.Flags.aapmApi()) {
+ EnforcingAdmin admin = dpm.getEnforcingAdmin(userId, userRestriction);
+ if (admin != null) {
+ return new EnforcedAdmin(admin.getComponentName(), userRestriction,
+ admin.getUserHandle());
+ }
+ }
+
final EnforcedAdmin admin =
getProfileOrDeviceOwner(context, userRestriction, enforcingUser.getUserHandle());
if (admin != null) {
@@ -838,6 +849,22 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
}
/**
+ * Checks if the identifier is enforced by advanced protection.
+ */
+ @RequiresApi(Build.VERSION_CODES.BAKLAVA)
+ public static boolean isPolicyEnforcedByAdvancedProtection(Context context, String identifier,
+ int userId) {
+ if (!android.security.Flags.aapmApi()) return false;
+ if (identifier == null) return false;
+ EnforcingAdmin admin = context.getSystemService(DevicePolicyManager.class)
+ .getEnforcingAdmin(userId, identifier);
+ if (admin == null) return false;
+ return admin.getAuthority() instanceof UnknownAuthority authority
+ && AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY.equals(
+ authority.getName());
+ }
+
+ /**
* Check if there are restrictions on an application from being a Credential Manager provider.
*
* @return EnforcedAdmin Object containing the enforced admin component and admin user details,
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 6ca9279de8c6..25628fba1b66 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -33,7 +33,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
@@ -118,10 +117,7 @@ public class RestrictedPreferenceHelper {
if (mDisabledSummary) {
final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
if (summaryView != null) {
- final CharSequence disabledText =
- (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
- ? getDisabledByAdminUpdatableString()
- : mContext.getString(R.string.disabled_by_admin_summary_text);
+ final CharSequence disabledText = getDisabledByAdminSummaryString();
if (mDisabledByAdmin) {
summaryView.setText(disabledText);
} else if (mDisabledByEcm) {
@@ -134,11 +130,23 @@ public class RestrictedPreferenceHelper {
}
}
- @RequiresApi(Build.VERSION_CODES.TIRAMISU)
- private String getDisabledByAdminUpdatableString() {
- return mContext.getSystemService(DevicePolicyManager.class).getResources().getString(
- CONTROLLED_BY_ADMIN_SUMMARY,
- () -> mContext.getString(R.string.disabled_by_admin_summary_text));
+ private String getDisabledByAdminSummaryString() {
+ if (isRestrictionEnforcedByAdvancedProtection()) {
+ return mContext.getString(com.android.settingslib.widget.restricted
+ .R.string.disabled_by_advanced_protection);
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ return mContext.getSystemService(DevicePolicyManager.class).getResources().getString(
+ CONTROLLED_BY_ADMIN_SUMMARY,
+ () -> mContext.getString(R.string.disabled_by_admin_summary_text));
+ }
+ return mContext.getString(R.string.disabled_by_admin_summary_text);
+ }
+
+ public boolean isRestrictionEnforcedByAdvancedProtection() {
+ return mEnforcedAdmin != null && RestrictedLockUtilsInternal
+ .isPolicyEnforcedByAdvancedProtection(mContext, mEnforcedAdmin.enforcedRestriction,
+ UserHandle.myUserId());
}
public void useAdminDisabledSummary(boolean useSummary) {
@@ -226,17 +234,24 @@ public class RestrictedPreferenceHelper {
*/
public boolean setDisabledByAdmin(EnforcedAdmin admin) {
boolean disabled = false;
+ boolean changed = false;
+ EnforcedAdmin previousAdmin = mEnforcedAdmin;
mEnforcedAdmin = null;
if (admin != null) {
disabled = true;
// Copy the received instance to prevent pass be reference being overwritten.
mEnforcedAdmin = new EnforcedAdmin(admin);
+ if (android.security.Flags.aapmApi()) {
+ changed = previousAdmin == null || !previousAdmin.equals(admin);
+ }
}
- boolean changed = false;
if (mDisabledByAdmin != disabled) {
mDisabledByAdmin = disabled;
changed = true;
+ }
+
+ if (changed) {
updateDisabledState();
}
@@ -286,6 +301,10 @@ public class RestrictedPreferenceHelper {
((PrimarySwitchPreference) mPreference).setSwitchEnabled(isEnabled);
}
+ if (android.security.Flags.aapmApi() && !isEnabled && mDisabledByAdmin) {
+ mPreference.setSummary(getDisabledByAdminSummaryString());
+ }
+
if (!isEnabled && mDisabledByEcm) {
mPreference.setSummary(R.string.disabled_by_app_ops_text);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 727dbe1019ae..0aac9a1104e9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -126,13 +126,7 @@ public class RestrictedSwitchPreference extends SwitchPreferenceCompat implement
CharSequence switchSummary;
if (mRestrictedSwitchSummary == null) {
- switchSummary = isChecked()
- ? getUpdatableEnterpriseString(
- getContext(), ENABLED_BY_ADMIN_SWITCH_SUMMARY,
- com.android.settingslib.widget.restricted.R.string.enabled_by_admin)
- : getUpdatableEnterpriseString(
- getContext(), DISABLED_BY_ADMIN_SWITCH_SUMMARY,
- com.android.settingslib.widget.restricted.R.string.disabled_by_admin);
+ switchSummary = getRestrictedSwitchSummary();
} else {
switchSummary = mRestrictedSwitchSummary;
}
@@ -177,6 +171,25 @@ public class RestrictedSwitchPreference extends SwitchPreferenceCompat implement
() -> context.getString(resId));
}
+ private String getRestrictedSwitchSummary() {
+ if (mHelper.isRestrictionEnforcedByAdvancedProtection()) {
+ final int apmResId = isChecked()
+ ? com.android.settingslib.widget.restricted.R.string
+ .enabled_by_advanced_protection
+ : com.android.settingslib.widget.restricted.R.string
+ .disabled_by_advanced_protection;
+ return getContext().getString(apmResId);
+ }
+
+ return isChecked()
+ ? getUpdatableEnterpriseString(
+ getContext(), ENABLED_BY_ADMIN_SWITCH_SUMMARY,
+ com.android.settingslib.widget.restricted.R.string.enabled_by_admin)
+ : getUpdatableEnterpriseString(
+ getContext(), DISABLED_BY_ADMIN_SWITCH_SUMMARY,
+ com.android.settingslib.widget.restricted.R.string.disabled_by_admin);
+ }
+
@Override
public void performClick() {
if (!mHelper.performClick()) {
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
index a2933d96e4a8..bb523d63c43a 100644
--- a/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
+++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowInstallUnknownSourcesAdvancedProtectionHook.java
@@ -118,6 +118,5 @@ public final class DisallowInstallUnknownSourcesAdvancedProtectionHook
+ " getAppOpPermissionPackages() threw the following exception: " + e);
}
}
- // TODO(b/369361373): Update dialog strings.
}
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6f0d26a2426d..a48fa5e99c32 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -117,6 +117,7 @@ import static android.app.admin.DeviceAdminInfo.USES_POLICY_FORCE_LOCK;
import static android.app.admin.DeviceAdminInfo.USES_POLICY_WIPE_DATA;
import static android.app.admin.DeviceAdminReceiver.ACTION_COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED;
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
+import static android.app.admin.DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY;
import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_FINANCING_STATE_CHANGED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
@@ -578,6 +579,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -591,6 +593,7 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* Implementation of the device policy APIs.
@@ -16234,6 +16237,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
result.putParcelable(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
admin.info.getComponent());
return result;
+ } else if (android.security.Flags.aapmApi()) {
+ result = new Bundle();
+ result.putInt(Intent.EXTRA_USER_ID, userId);
+ return result;
}
return null;
} finally {
@@ -16243,6 +16250,54 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return null;
}
+ private android.app.admin.EnforcingAdmin getEnforcingAdminInternal(int userId,
+ String identifier) {
+ Objects.requireNonNull(identifier);
+
+ Set<EnforcingAdmin> admins = getEnforcingAdminsForIdentifier(userId, identifier);
+ if (admins.isEmpty()) {
+ return null;
+ }
+
+ final EnforcingAdmin admin;
+ if (admins.size() == 1) {
+ admin = admins.iterator().next();
+ } else {
+ Optional<EnforcingAdmin> dpc = admins.stream()
+ .filter(a -> a.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)).findFirst();
+ admin = dpc.orElseGet(() -> admins.stream().findFirst().get());
+ }
+ return admin == null ? null : admin.getParcelableAdmin();
+ }
+
+ private <V> Set<EnforcingAdmin> getEnforcingAdminsForIdentifier(int userId, String identifier) {
+ // For POLICY_SUSPEND_PACKAGES return PO or DO to keep the behavior same as
+ // before the bug fix for b/192245204.
+ if (DevicePolicyManager.POLICY_SUSPEND_PACKAGES.equals(identifier)) {
+ EnforcingAdmin admin = getProfileOrDeviceOwnerEnforcingAdmin(userId);
+ return admin == null ? Collections.emptySet() : Collections.singleton(admin);
+ }
+
+ long ident = mInjector.binderClearCallingIdentity();
+ try {
+ final PolicyDefinition<V> policyDefinition = getPolicyDefinitionForIdentifier(
+ identifier);
+ V value = mDevicePolicyEngine.getResolvedPolicy(policyDefinition, userId);
+ if (value == null) {
+ return Collections.emptySet();
+ }
+ return Stream.concat(mDevicePolicyEngine.getGlobalPoliciesSetByAdmins(policyDefinition)
+ .entrySet().stream(),
+ mDevicePolicyEngine.getLocalPoliciesSetByAdmins(policyDefinition,
+ userId).entrySet().stream())
+ .filter(entry -> value.equals(entry.getValue().getValue()))
+ .map(Map.Entry::getKey)
+ .collect(Collectors.toSet());
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
+ }
+
/**
* @param restriction The restriction enforced by admin. It could be any user restriction or
* policy like {@link DevicePolicyManager#POLICY_DISABLE_CAMERA},
@@ -16257,20 +16312,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
// before the bug fix for b/192245204.
if (DevicePolicyManager.POLICY_SUSPEND_PACKAGES.equals(
restriction)) {
- ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
- if (profileOwner != null) {
- EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
- profileOwner, userId);
- admins.add(admin.getParcelableAdmin());
- return admins;
- }
- final Pair<Integer, ComponentName> deviceOwner =
- mOwners.getDeviceOwnerUserIdAndComponent();
- if (deviceOwner != null && deviceOwner.first == userId) {
- EnforcingAdmin admin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
- deviceOwner.second, deviceOwner.first);
+ EnforcingAdmin admin = getProfileOrDeviceOwnerEnforcingAdmin(userId);
+ if (admin != null) {
admins.add(admin.getParcelableAdmin());
- return admins;
}
} else {
long ident = mInjector.binderClearCallingIdentity();
@@ -16319,6 +16363,29 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ private static <V> PolicyDefinition<V> getPolicyDefinitionForIdentifier(
+ @NonNull String identifier) {
+ Objects.requireNonNull(identifier);
+ if (Flags.setMtePolicyCoexistence() && MEMORY_TAGGING_POLICY.equals(identifier)) {
+ return (PolicyDefinition<V>) PolicyDefinition.MEMORY_TAGGING;
+ } else {
+ return (PolicyDefinition<V>) getPolicyDefinitionForRestriction(identifier);
+ }
+ }
+
+ private EnforcingAdmin getProfileOrDeviceOwnerEnforcingAdmin(int userId) {
+ ComponentName profileOwner = mOwners.getProfileOwnerComponent(userId);
+ if (profileOwner != null) {
+ return EnforcingAdmin.createEnterpriseEnforcingAdmin(profileOwner, userId);
+ }
+ final Pair<Integer, ComponentName> deviceOwner = mOwners.getDeviceOwnerUserIdAndComponent();
+ if (deviceOwner != null && deviceOwner.first == userId) {
+ return EnforcingAdmin.createEnterpriseEnforcingAdmin(deviceOwner.second,
+ deviceOwner.first);
+ }
+ return null;
+ }
+
private static String userRestrictionSourceToString(@UserRestrictionSource int source) {
return DebugUtils.flagsToString(UserManager.class, "RESTRICTION_", source);
}
@@ -16336,6 +16403,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
+ public android.app.admin.EnforcingAdmin getEnforcingAdmin(int userId, String identifier) {
+ Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()));
+ return getEnforcingAdminInternal(userId, identifier);
+ }
+
+ @Override
public List<android.app.admin.EnforcingAdmin> getEnforcingAdminsForRestriction(
int userId, String restriction) {
Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()));
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
index 1fd628a20afa..5a0b079b6a24 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/EnforcingAdmin.java
@@ -321,8 +321,10 @@ final class EnforcingAdmin {
authority = DpcAuthority.DPC_AUTHORITY;
} else if (mAuthorities.contains(DEVICE_ADMIN_AUTHORITY)) {
authority = DeviceAdminAuthority.DEVICE_ADMIN_AUTHORITY;
+ } else if (mIsSystemAuthority) {
+ // For now, System Authority returns UnknownAuthority.
+ authority = new UnknownAuthority(mSystemEntity);
} else {
- // For now, System Authority returns UNKNOWN_AUTHORITY.
authority = UnknownAuthority.UNKNOWN_AUTHORITY;
}
return new android.app.admin.EnforcingAdmin(