Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc15d51f authored by Irem Uguz's avatar Irem Uguz Committed by Android (Google) Code Review
Browse files

Merge changes from topic "iremuguz-keyguard-supervision-admin" into main

* changes:
  Introduce getEnforcingAdminsForKeyguardFeatures
  Use EnforcingAdmin in restricted settings
parents fbfad32e db73c865
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.settingslib;

import android.app.admin.EnforcingAdmin;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
@@ -159,6 +160,15 @@ public class PrimarySwitchPreference extends RestrictedPreference {
        setSwitchEnabled(admin == null);
    }

    /**
     * If admin is not null, disables the switch.
     * Otherwise, keep it enabled.
     */
    public void setDisabledByAdmin(EnforcingAdmin admin) {
        super.setDisabledByAdmin(admin);
        setSwitchEnabled(admin == null);
    }

    public CompoundButton getSwitch() {
        return mSwitch;
    }
+82 −0
Original line number Diff line number Diff line
@@ -26,9 +26,11 @@ import static com.android.settingslib.Utils.getColorAttrDefaultColor;
import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyIdentifiers;
import android.app.admin.DevicePolicyManager;
import android.app.admin.EnforcingAdmin;
import android.app.admin.PackagePolicy;
import android.app.admin.PolicyEnforcementInfo;
import android.app.admin.SystemAuthority;
import android.app.ecm.EnhancedConfirmationManager;
import android.app.role.RoleManager;
@@ -272,6 +274,53 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
        return checkForLockSetting(context, userId, check);
    }

    /**
     * Checks whether keyguard features are disabled by policy and returns the admin information.
     *
     * @param context          {@link Context} for the calling user.
     * @param keyguardFeatures Any one of keyguard features that can be disabled by {@link
     *                         android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures}.
     * @param userId           User to check keyguard features for.
     * @return PolicyEnforcementInfo Object containing the enforcing admin information. null if
     * keyguard features are not disabled.
     * @throws IllegalStateException if
     * {@link android.app.admin.flags.Flags#setKeyguardDisabledFeaturesCoexistence} is not enabled.
     * When the flag is disabled, please use {@link #checkIfKeyguardFeaturesDisabled} instead.
     */
    @RequiresApi(Build.VERSION_CODES.BAKLAVA)
    public static PolicyEnforcementInfo getEnforcingAdminsForKeyguardFeatures(Context context,
            int keyguardFeatures, @UserIdInt int userId) {
        // TODO(b/359186276): Remove this check once the flag is ready for clean-up.
        if (!android.app.admin.flags.Flags.setKeyguardDisabledFeaturesCoexistence()) {
            throw new IllegalStateException(
                    "setKeyguardDisabledFeaturesCoexistence is not enabled. Use "
                            + "checkIfKeyguardFeaturesDisabled instead.");
        }

        DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
        if (dpm == null) {
            Log.w(LOG_TAG, "DevicePolicyManager is null");
            return null;
        }

        if (!isKeyguardFeaturesDisabled(dpm, keyguardFeatures, userId)) {
            return null;
        }

        // We don't need to check separately for managed profile or parent profile policies as
        // the policy application is handled by DPM in {@link android.app.admin
        // .DevicePolicyManager#setKeyguardDisabledFeatures} already.
        return dpm.getEnforcingAdminsForPolicy(
                DevicePolicyIdentifiers.KEYGUARD_DISABLED_FEATURES_POLICY, userId);
    }

    private static boolean isKeyguardFeaturesDisabled(DevicePolicyManager dpm, int keyguardFeatures,
            int userId) {
        // Set admin as null to check for all admins who has set policy.
        int disabledFeatures = dpm.getKeyguardDisabledFeatures(/*admin=*/null, userId);
        return (disabledFeatures & keyguardFeatures) != KEYGUARD_DISABLE_FEATURES_NONE;
    }

    /**
     * @return the UserHandle for a userId. Return null for USER_NULL
     */
@@ -779,6 +828,39 @@ public class RestrictedLockUtilsInternal extends RestrictedLockUtils {
        item.setTitle(sb);
    }

    /**
     * Set the menu item as disabled by admin by adding a restricted padlock at the end of the
     * text and set the click listener which will send an intent to show the admin support details
     * dialog. If the admin is null, remove the padlock and disabled color span. When the admin is
     * null, we also set the OnMenuItemClickListener to null, so if you want to set a custom
     * OnMenuItemClickListener, set it after calling this method.
     */
    public static void setMenuItemAsDisabledByAdmin(final Context context,
            final MenuItem item, final EnforcingAdmin admin, final String restriction) {
        SpannableStringBuilder sb = new SpannableStringBuilder(item.getTitle());
        removeExistingRestrictedSpans(sb);

        if (admin != null) {
            final int disabledColor = getColorAttrDefaultColor(context,
                    android.R.attr.textColorHint);
            sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(),
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            ImageSpan image = new RestrictedLockImageSpan(context);
            sb.append(" ", image, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {
                    sendShowAdminSupportDetailsIntent(context, admin, restriction);
                    return true;
                }
            });
        } else {
            item.setOnMenuItemClickListener(null);
        }
        item.setTitle(sb);
    }

    private static void removeExistingRestrictedSpans(SpannableStringBuilder sb) {
        final int length = sb.length();
        RestrictedLockImageSpan[] imageSpans = sb.getSpans(length - 1, length,
+11 −0
Original line number Diff line number Diff line
@@ -18,12 +18,14 @@ package com.android.settingslib;

import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import android.app.admin.EnforcingAdmin;
import android.content.Context;
import android.os.Process;
import android.os.UserHandle;
import android.util.AttributeSet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
@@ -149,6 +151,15 @@ public class RestrictedPreference extends TwoTargetPreference implements
        }
    }

    /**
     * Sets the admin that disabled this preference.
     */
    public void setDisabledByAdmin(@Nullable EnforcingAdmin admin) {
        if (mHelper.setDisabledByEnforcingAdmin(admin)) {
            notifyChanged();
        }
    }

    public boolean isDisabledByAdmin() {
        return mHelper.isDisabledByAdmin();
    }
+2 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import android.annotation.UserIdInt;
import android.app.AlertDialog;
import android.app.admin.EnforcingAdmin;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
@@ -217,7 +218,7 @@ public class InputMethodPreference extends PrimarySwitchPreference
        // This preference should also be disabled in case the admin does not allow this input
        // method.
        if (isAlwaysChecked) {
            setDisabledByAdmin(null);
            setDisabledByAdmin((EnforcingAdmin) null);
            setSwitchEnabled(false);
        } else if (!mIsAllowedByOrganization) {
            EnforcedAdmin admin =
+37 −3
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
package com.android.settingslib.supervision

import android.app.admin.DeviceAdminReceiver
import android.app.admin.EnforcingAdmin
import android.app.admin.RoleAuthority
import android.app.role.RoleManager
import android.app.supervision.SupervisionAppService
import android.app.supervision.SupervisionManager
import android.content.ComponentName
@@ -40,6 +43,37 @@ object SupervisionRestrictionsHelper {
        restriction: String,
        user: UserHandle,
    ): EnforcedAdmin? {
        if (!supervisionEnabled(context, user.identifier)) {
            return null
        }
        return EnforcedAdmin(getSupervisionComponent(context, user.identifier), restriction, user)
    }

    /**
     * Creates an instance of [EnforcingAdmin] that uses the correct supervision component or
     * returns null if supervision is not enabled.
     */
    @JvmStatic
    fun createEnforcingAdmin(context: Context, user: UserHandle): EnforcingAdmin? {
        if (!supervisionEnabled(context, user.identifier)) {
            return null
        }
        val componentName = getSupervisionComponent(context, user.identifier)
        val packageName = componentName?.packageName ?: ""
        return EnforcingAdmin(
            packageName,
            RoleAuthority(setOf(RoleManager.ROLE_SYSTEM_SUPERVISION)),
            user,
            componentName,
        )
    }

    private fun supervisionEnabled(context: Context, userId: Int): Boolean {
        val supervisionManager = context.getSystemService(SupervisionManager::class.java)
        return supervisionManager?.isSupervisionEnabledForUser(userId) == true
    }

    private fun getSupervisionComponent(context: Context, userId: Int): ComponentName? {
        val supervisionManager = context.getSystemService(SupervisionManager::class.java)
        val supervisionAppPackage = supervisionManager?.activeSupervisionAppPackage ?: return null
        var supervisionComponent: ComponentName? = null
@@ -49,7 +83,7 @@ object SupervisionRestrictionsHelper {
            context.packageManager.queryIntentServicesAsUser(
                Intent(SupervisionAppService.ACTION_SUPERVISION_APP_SERVICE),
                PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS,
                user.identifier,
                userId,
            )
        resolveSupervisionApps
            .mapNotNull { it.serviceInfo?.componentName }
@@ -63,7 +97,7 @@ object SupervisionRestrictionsHelper {
                context.packageManager.queryBroadcastReceiversAsUser(
                    Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
                    PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS,
                    user.identifier,
                    userId,
                )
            resolveDeviceAdmins
                .mapNotNull { it.activityInfo?.componentName }
@@ -74,6 +108,6 @@ object SupervisionRestrictionsHelper {
        if (supervisionComponent == null) {
            Log.d(SupervisionLog.TAG, "Could not find the supervision component.")
        }
        return EnforcedAdmin(supervisionComponent, restriction, user)
        return supervisionComponent
    }
}
Loading