Loading core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -1552,6 +1552,7 @@ package android.app.admin { ctor public EnforcingAdmin(@NonNull String, @NonNull android.app.admin.Authority, @NonNull android.os.UserHandle); method public int describeContents(); method @NonNull public android.app.admin.Authority getAuthority(); method @FlaggedApi("android.app.admin.flags.enforcing_admin_get_component_name_enabled") @Nullable public android.content.ComponentName getComponentName(); method @NonNull public String getPackageName(); method @NonNull public android.os.UserHandle getUserHandle(); method public void writeToParcel(@NonNull android.os.Parcel, int); core/java/android/app/admin/EnforcingAdmin.java +4 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.app.admin; import static android.app.admin.flags.Flags.FLAG_ENFORCING_ADMIN_GET_COMPONENT_NAME_ENABLED; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; Loading @@ -38,10 +41,6 @@ public final class EnforcingAdmin implements Parcelable { private final String mPackageName; private final Authority mAuthority; private final UserHandle mUserHandle; /** * @hide */ private final ComponentName mComponentName; /** Loading Loading @@ -105,9 +104,8 @@ public final class EnforcingAdmin implements Parcelable { /** * Returns the {@link ComponentName} of the admin if applicable. * * @hide */ @FlaggedApi(FLAG_ENFORCING_ADMIN_GET_COMPONENT_NAME_ENABLED) @Nullable public ComponentName getComponentName() { return mComponentName; Loading core/java/android/app/admin/flags/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -484,3 +484,11 @@ flag { description: "Enable the policy streamlining APIs." bug: "434919316" } flag { name: "enforcing_admin_get_component_name_enabled" namespace: "enterprise" description: "Enables the getter API for componentName field of EnforcingAdmin" bug: "414733570" is_exported: true } packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java +31 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settingslib; import android.app.admin.DevicePolicyManager; import android.app.admin.EnforcingAdmin; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -26,6 +27,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; Loading Loading @@ -118,6 +120,35 @@ public class RestrictedLockUtils { return intent; } /** Gets the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}. */ @RequiresApi(Build.VERSION_CODES.BAKLAVA) @NonNull public static Intent getShowAdminSupportDetailsIntent(@Nullable EnforcingAdmin admin) { final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); if (admin != null) { if (admin.getComponentName() != null) { intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.getComponentName()); } intent.putExtra(Intent.EXTRA_USER, admin.getUserHandle()); } return intent; } /** Sends the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}. */ @RequiresApi(Build.VERSION_CODES.BAKLAVA) public static void sendShowAdminSupportDetailsIntent( @NonNull Context context, @Nullable EnforcingAdmin admin, @NonNull String restriction) { final Intent intent = getShowAdminSupportDetailsIntent(admin); int targetUserId = UserHandle.myUserId(); if (admin != null) { if (isCurrentUserOrProfile(context, admin.getUserHandle().getIdentifier())) { targetUserId = admin.getUserHandle().getIdentifier(); } intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, restriction); } context.startActivityAsUser(intent, UserHandle.of(targetUserId)); } /** * Checks if current user is profile or not */ Loading packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java +83 −9 Original line number Diff line number Diff line Loading @@ -21,6 +21,9 @@ import static android.app.admin.DevicePolicyResources.Strings.Settings.CONTROLLE import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.admin.DevicePolicyManager; import android.app.admin.EnforcingAdmin; import android.app.admin.UnknownAuthority; import android.app.admin.flags.Flags; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; Loading @@ -37,6 +40,8 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import java.util.Objects; /** * Helper class for managing settings preferences that can be disabled * by device admins via user restrictions. Loading @@ -45,6 +50,9 @@ public class RestrictedPreferenceHelper { private static final String TAG = "RestrictedPreferenceHelper"; private static final String REASON_PHONE_STATE = "phone_state"; // For the admin components that don't have any package name defined, we use default one as // empty string. private static final String DEFAULT_ADMIN_PACKAGE_NAME = ""; private final Context mContext; private final Preference mPreference; Loading @@ -58,7 +66,10 @@ public class RestrictedPreferenceHelper { int uid; private boolean mDisabledByAdmin; private EnforcingAdmin mEnforcingAdmin; @VisibleForTesting // TODO(b/414733570): Remove when feature is enabled and all calls have moved to use // mEnforcingAdmin. EnforcedAdmin mEnforcedAdmin; private String mAttrUserRestriction = null; private boolean mDisabledSummary = false; Loading Loading @@ -146,9 +157,17 @@ public class RestrictedPreferenceHelper { } public boolean isRestrictionEnforcedByAdvancedProtection() { return mEnforcedAdmin != null && RestrictedLockUtilsInternal .isPolicyEnforcedByAdvancedProtection(mContext, mEnforcedAdmin.enforcedRestriction, UserHandle.myUserId()); if (Flags.policyTransparencyRefactorEnabled()) { return mEnforcingAdmin != null && RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(mContext, // When the feature is enabled and we're using mEnforcingAdmin, the user // restriction is always stored on mAttrUserRestriction. mAttrUserRestriction, UserHandle.myUserId()); } else { return mEnforcedAdmin != null && RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(mContext, mEnforcedAdmin.enforcedRestriction, UserHandle.myUserId()); } } /** Loading @@ -175,7 +194,12 @@ public class RestrictedPreferenceHelper { @SuppressWarnings("NewApi") public boolean performClick() { if (mDisabledByAdmin) { if (Flags.policyTransparencyRefactorEnabled()) { RestrictedLockUtils.sendShowAdminSupportDetailsIntent( mContext, mEnforcingAdmin, mAttrUserRestriction); } else { RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin); } return true; } if (mDisabledByEcm) { Loading Loading @@ -258,12 +282,23 @@ public class RestrictedPreferenceHelper { /** * Disable this preference based on the enforce admin. * * @param admin details of the admin who enforced the restriction. If it is * {@code null}, then this preference will be enabled. Otherwise, it will be disabled. * Only gray out the preference which is not {@link RestrictedTopLevelPreference}. * @param admin details of the admin who enforced the restriction. If it is {@code null}, then * this preference will be enabled. Otherwise, it will be disabled. Only gray out the * preference which is not {@link RestrictedTopLevelPreference}. * @return true if the disabled state was changed. */ public boolean setDisabledByAdmin(EnforcedAdmin admin) { if (Flags.policyTransparencyRefactorEnabled()) { EnforcingAdmin enforcingAdmin = getEnforcingAdminFromEnforcedAdmin(admin); // Ensure that mAttrUserRestriction is set to the value passed in admin if it's unset. // If it's already set, we don't need to update the value. if (admin != null && mAttrUserRestriction == null) { mAttrUserRestriction = admin.enforcedRestriction; } return setDisabledByEnforcingAdmin(enforcingAdmin); } // TODO(b/414733570): Cleanup when Flags.policyTransparencyRefactorEnabled() is fully // rolled out. boolean disabled = false; boolean changed = false; EnforcedAdmin previousAdmin = mEnforcedAdmin; Loading @@ -289,6 +324,34 @@ public class RestrictedPreferenceHelper { return changed; } /** * Disable this preference based on the enforcing admin. Note that this doesn't set the * restriction that this preference tracks. To set the restriction, call * {@link #setUserRestriction} or set it through XML attribute * {@link R.styleable#RestrictedPreference_userRestriction}. * * @param admin details of the admin who enforced the restriction. If it is {@code null}, then * this preference will be enabled. Otherwise, it will be disabled. Only gray out * the * preference which is not {@link RestrictedTopLevelPreference}. * @return true if the disabled state was changed. */ public boolean setDisabledByEnforcingAdmin(@Nullable EnforcingAdmin admin) { final boolean disabled = (admin != null); final boolean adminChanged = !Objects.equals(mEnforcingAdmin, admin); final boolean disabledStateChanged = mDisabledByAdmin != disabled; mEnforcingAdmin = admin; mDisabledByAdmin = disabled; final boolean changed = adminChanged || disabledStateChanged; if (changed) { updateDisabledState(); } return changed; } /** * Disable the preference based on the passed in Intent * @param disabledIntent The intent which is started when the user clicks the disabled Loading Loading @@ -368,4 +431,15 @@ public class RestrictedPreferenceHelper { return changed; } private EnforcingAdmin getEnforcingAdminFromEnforcedAdmin(EnforcedAdmin admin) { // Check the nullable fields of EnforcedAdmin and replace with appropriate values for null // as EnforcingAdmin has non-null fields. return admin == null ? null : new EnforcingAdmin( admin.component == null ? DEFAULT_ADMIN_PACKAGE_NAME : admin.component.getPackageName(), UnknownAuthority.UNKNOWN_AUTHORITY, admin.user == null ? UserHandle.of(UserHandle.myUserId()) : admin.user, admin.component); } } Loading
core/api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -1552,6 +1552,7 @@ package android.app.admin { ctor public EnforcingAdmin(@NonNull String, @NonNull android.app.admin.Authority, @NonNull android.os.UserHandle); method public int describeContents(); method @NonNull public android.app.admin.Authority getAuthority(); method @FlaggedApi("android.app.admin.flags.enforcing_admin_get_component_name_enabled") @Nullable public android.content.ComponentName getComponentName(); method @NonNull public String getPackageName(); method @NonNull public android.os.UserHandle getUserHandle(); method public void writeToParcel(@NonNull android.os.Parcel, int);
core/java/android/app/admin/EnforcingAdmin.java +4 −6 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.app.admin; import static android.app.admin.flags.Flags.FLAG_ENFORCING_ADMIN_GET_COMPONENT_NAME_ENABLED; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; Loading @@ -38,10 +41,6 @@ public final class EnforcingAdmin implements Parcelable { private final String mPackageName; private final Authority mAuthority; private final UserHandle mUserHandle; /** * @hide */ private final ComponentName mComponentName; /** Loading Loading @@ -105,9 +104,8 @@ public final class EnforcingAdmin implements Parcelable { /** * Returns the {@link ComponentName} of the admin if applicable. * * @hide */ @FlaggedApi(FLAG_ENFORCING_ADMIN_GET_COMPONENT_NAME_ENABLED) @Nullable public ComponentName getComponentName() { return mComponentName; Loading
core/java/android/app/admin/flags/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -484,3 +484,11 @@ flag { description: "Enable the policy streamlining APIs." bug: "434919316" } flag { name: "enforcing_admin_get_component_name_enabled" namespace: "enterprise" description: "Enables the getter API for componentName field of EnforcingAdmin" bug: "414733570" is_exported: true }
packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java +31 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.settingslib; import android.app.admin.DevicePolicyManager; import android.app.admin.EnforcingAdmin; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -26,6 +27,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; Loading Loading @@ -118,6 +120,35 @@ public class RestrictedLockUtils { return intent; } /** Gets the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}. */ @RequiresApi(Build.VERSION_CODES.BAKLAVA) @NonNull public static Intent getShowAdminSupportDetailsIntent(@Nullable EnforcingAdmin admin) { final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); if (admin != null) { if (admin.getComponentName() != null) { intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.getComponentName()); } intent.putExtra(Intent.EXTRA_USER, admin.getUserHandle()); } return intent; } /** Sends the intent to trigger the {@code android.settings.ShowAdminSupportDetailsDialog}. */ @RequiresApi(Build.VERSION_CODES.BAKLAVA) public static void sendShowAdminSupportDetailsIntent( @NonNull Context context, @Nullable EnforcingAdmin admin, @NonNull String restriction) { final Intent intent = getShowAdminSupportDetailsIntent(admin); int targetUserId = UserHandle.myUserId(); if (admin != null) { if (isCurrentUserOrProfile(context, admin.getUserHandle().getIdentifier())) { targetUserId = admin.getUserHandle().getIdentifier(); } intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, restriction); } context.startActivityAsUser(intent, UserHandle.of(targetUserId)); } /** * Checks if current user is profile or not */ Loading
packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java +83 −9 Original line number Diff line number Diff line Loading @@ -21,6 +21,9 @@ import static android.app.admin.DevicePolicyResources.Strings.Settings.CONTROLLE import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import android.app.admin.DevicePolicyManager; import android.app.admin.EnforcingAdmin; import android.app.admin.UnknownAuthority; import android.app.admin.flags.Flags; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; Loading @@ -37,6 +40,8 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceViewHolder; import java.util.Objects; /** * Helper class for managing settings preferences that can be disabled * by device admins via user restrictions. Loading @@ -45,6 +50,9 @@ public class RestrictedPreferenceHelper { private static final String TAG = "RestrictedPreferenceHelper"; private static final String REASON_PHONE_STATE = "phone_state"; // For the admin components that don't have any package name defined, we use default one as // empty string. private static final String DEFAULT_ADMIN_PACKAGE_NAME = ""; private final Context mContext; private final Preference mPreference; Loading @@ -58,7 +66,10 @@ public class RestrictedPreferenceHelper { int uid; private boolean mDisabledByAdmin; private EnforcingAdmin mEnforcingAdmin; @VisibleForTesting // TODO(b/414733570): Remove when feature is enabled and all calls have moved to use // mEnforcingAdmin. EnforcedAdmin mEnforcedAdmin; private String mAttrUserRestriction = null; private boolean mDisabledSummary = false; Loading Loading @@ -146,9 +157,17 @@ public class RestrictedPreferenceHelper { } public boolean isRestrictionEnforcedByAdvancedProtection() { return mEnforcedAdmin != null && RestrictedLockUtilsInternal .isPolicyEnforcedByAdvancedProtection(mContext, mEnforcedAdmin.enforcedRestriction, UserHandle.myUserId()); if (Flags.policyTransparencyRefactorEnabled()) { return mEnforcingAdmin != null && RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(mContext, // When the feature is enabled and we're using mEnforcingAdmin, the user // restriction is always stored on mAttrUserRestriction. mAttrUserRestriction, UserHandle.myUserId()); } else { return mEnforcedAdmin != null && RestrictedLockUtilsInternal.isPolicyEnforcedByAdvancedProtection(mContext, mEnforcedAdmin.enforcedRestriction, UserHandle.myUserId()); } } /** Loading @@ -175,7 +194,12 @@ public class RestrictedPreferenceHelper { @SuppressWarnings("NewApi") public boolean performClick() { if (mDisabledByAdmin) { if (Flags.policyTransparencyRefactorEnabled()) { RestrictedLockUtils.sendShowAdminSupportDetailsIntent( mContext, mEnforcingAdmin, mAttrUserRestriction); } else { RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, mEnforcedAdmin); } return true; } if (mDisabledByEcm) { Loading Loading @@ -258,12 +282,23 @@ public class RestrictedPreferenceHelper { /** * Disable this preference based on the enforce admin. * * @param admin details of the admin who enforced the restriction. If it is * {@code null}, then this preference will be enabled. Otherwise, it will be disabled. * Only gray out the preference which is not {@link RestrictedTopLevelPreference}. * @param admin details of the admin who enforced the restriction. If it is {@code null}, then * this preference will be enabled. Otherwise, it will be disabled. Only gray out the * preference which is not {@link RestrictedTopLevelPreference}. * @return true if the disabled state was changed. */ public boolean setDisabledByAdmin(EnforcedAdmin admin) { if (Flags.policyTransparencyRefactorEnabled()) { EnforcingAdmin enforcingAdmin = getEnforcingAdminFromEnforcedAdmin(admin); // Ensure that mAttrUserRestriction is set to the value passed in admin if it's unset. // If it's already set, we don't need to update the value. if (admin != null && mAttrUserRestriction == null) { mAttrUserRestriction = admin.enforcedRestriction; } return setDisabledByEnforcingAdmin(enforcingAdmin); } // TODO(b/414733570): Cleanup when Flags.policyTransparencyRefactorEnabled() is fully // rolled out. boolean disabled = false; boolean changed = false; EnforcedAdmin previousAdmin = mEnforcedAdmin; Loading @@ -289,6 +324,34 @@ public class RestrictedPreferenceHelper { return changed; } /** * Disable this preference based on the enforcing admin. Note that this doesn't set the * restriction that this preference tracks. To set the restriction, call * {@link #setUserRestriction} or set it through XML attribute * {@link R.styleable#RestrictedPreference_userRestriction}. * * @param admin details of the admin who enforced the restriction. If it is {@code null}, then * this preference will be enabled. Otherwise, it will be disabled. Only gray out * the * preference which is not {@link RestrictedTopLevelPreference}. * @return true if the disabled state was changed. */ public boolean setDisabledByEnforcingAdmin(@Nullable EnforcingAdmin admin) { final boolean disabled = (admin != null); final boolean adminChanged = !Objects.equals(mEnforcingAdmin, admin); final boolean disabledStateChanged = mDisabledByAdmin != disabled; mEnforcingAdmin = admin; mDisabledByAdmin = disabled; final boolean changed = adminChanged || disabledStateChanged; if (changed) { updateDisabledState(); } return changed; } /** * Disable the preference based on the passed in Intent * @param disabledIntent The intent which is started when the user clicks the disabled Loading Loading @@ -368,4 +431,15 @@ public class RestrictedPreferenceHelper { return changed; } private EnforcingAdmin getEnforcingAdminFromEnforcedAdmin(EnforcedAdmin admin) { // Check the nullable fields of EnforcedAdmin and replace with appropriate values for null // as EnforcingAdmin has non-null fields. return admin == null ? null : new EnforcingAdmin( admin.component == null ? DEFAULT_ADMIN_PACKAGE_NAME : admin.component.getPackageName(), UnknownAuthority.UNKNOWN_AUTHORITY, admin.user == null ? UserHandle.of(UserHandle.myUserId()) : admin.user, admin.component); } }