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

Commit 7c66c9b6 authored by Irem Uguz's avatar Irem Uguz
Browse files

Use EnforcingAdmin on RestrictedPreferenceHelper

This patch adds methods to use the EnforcingAdmin class in
RestrictedPreferenceHelper and RestrictedLockUtils. It will allow to use
new DevicePolicyManager API (added in ag/34058536) to get enforcing
admin in follow-up changes.

This change also exposes EnforcingAdmin::getComponentName() method to
allow RestrictedLockUtils to access it. Previously, it was an hidden
API.

Flag: android.app.admin.flags.policy_transparency_refactor_enabled
Flag: android.app.admin.flags.enforcing_admin_get_component_name_enabled
Bug: 414733570
FCRS_CODE : mcolh0glw6rmhp
Test: atest RestrictedLockUtilsTest
Test: atest RestrictedPreferenceHelperTest

Change-Id: I39ba376d27231f0285575862b8ef44aa7ebb9c7b
parent 4bee8c55
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+4 −6
Original line number Diff line number Diff line
@@ -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;
@@ -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;

    /**
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -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
}
+31 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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
     */
+83 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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.
@@ -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;
@@ -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;
@@ -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());
        }
    }

    /**
@@ -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) {
@@ -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;
@@ -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
@@ -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