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

Commit ae132a63 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update the order of admins in PolicyEnforcementInfo" into main

parents 4d7ff663 1cf6480b
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -16,13 +16,11 @@

package android.app.admin;

import static java.util.function.Predicate.not;

import android.annotation.Nullable;
import android.app.role.RoleManager;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

/**
 * Class that contains information about the admins that are enforcing a specific policy.
@@ -30,22 +28,23 @@ import java.util.stream.Stream;
 * @hide
 */
public class PolicyEnforcementInfo {
    // Contains all admins who has enforced the policy. The supervision admin will be first on
    // the list, if there's any.
    // Contains all admins who has enforced the policy. The admins will be ordered as
    // supervision, DPC admin then any other admin if they exist in the list.
    private final List<EnforcingAdmin> mAllAdmins;

    /**
     * @hide
     */
    public PolicyEnforcementInfo(List<EnforcingAdmin> enforcingAdmins) {
        // Add any supervisor admins first.
        Stream<EnforcingAdmin> supervisorAdmins = enforcingAdmins.stream().filter(
                PolicyEnforcementInfo::isSupervisionRole);
        // Add all other admins afterwards. Only supervisor admin will be added first, for others
        // the order doesn't matter.
        Stream<EnforcingAdmin> otherAdmins = enforcingAdmins.stream().filter(
                not(PolicyEnforcementInfo::isSupervisionRole));
        mAllAdmins = Stream.concat(supervisorAdmins, otherAdmins).toList();
        mAllAdmins = enforcingAdmins.stream().sorted(Comparator.comparingInt(admin -> {
            if (isSupervisionRole(admin)) {
                return 0; // Supervision role holders have the highest priority.
            }
            if (isDpcAdmin(admin)) {
                return 1; // DPC are next.
            }
            return 2; // All other admins at the end.
        })).toList();
    }

    /**
@@ -88,4 +87,8 @@ public class PolicyEnforcementInfo {
        return ((RoleAuthority) enforcingAdmin.getAuthority()).getRoles().contains(
                RoleManager.ROLE_SYSTEM_SUPERVISION);
    }

    private static boolean isDpcAdmin(EnforcingAdmin enforcingAdmin) {
        return enforcingAdmin.getAuthority() instanceof DpcAuthority;
    }
}
+105 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.devicepolicy

import android.app.admin.DpcAuthority
import android.app.admin.PolicyEnforcementInfo
import android.app.admin.RoleAuthority
import android.app.admin.SystemAuthority
import android.app.role.RoleManager
import android.content.ComponentName
import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class PolicyEnforcementInfoTest {

    @Test
    fun getAllAdmins_sortsAdmins_supervisionAdminDpcAdminOtherAdmin() {
        val policyEnforcementInfo =
            PolicyEnforcementInfo(listOf(DPC_ADMIN, SYSTEM_ADMIN, SUPERVISION_ADMIN))
        assertThat(policyEnforcementInfo.allAdmins)
            .containsExactly(SUPERVISION_ADMIN, DPC_ADMIN, SYSTEM_ADMIN)
            .inOrder()
    }

    @Test
    fun getAllAdmins_sortsAdmins_dpcAdminOtherAdmin() {
        val policyEnforcementInfo = PolicyEnforcementInfo(listOf(SYSTEM_ADMIN, DPC_ADMIN))
        assertThat(policyEnforcementInfo.allAdmins)
            .containsExactly(DPC_ADMIN, SYSTEM_ADMIN)
            .inOrder()
    }

    @Test
    fun isOnlyEnforcedBySystem_returnsFalse() {
        val policyEnforcementInfo =
            PolicyEnforcementInfo(listOf(SYSTEM_ADMIN, SUPERVISION_ADMIN, DPC_ADMIN))
        assertThat(policyEnforcementInfo.isOnlyEnforcedBySystem).isFalse()
    }

    @Test
    fun isOnlyEnforcedBySystem_returnsTrue() {
        val policyEnforcementInfo = PolicyEnforcementInfo(listOf(SYSTEM_ADMIN))
        assertThat(policyEnforcementInfo.isOnlyEnforcedBySystem).isTrue()
    }

    @Test
    fun getMostImportantEnforcingAdmin_returnsSupervisionAdmin() {
        val policyEnforcementInfo =
            PolicyEnforcementInfo(listOf(SUPERVISION_ADMIN, DPC_ADMIN, SYSTEM_ADMIN))
        assertThat(policyEnforcementInfo.mostImportantEnforcingAdmin).isEqualTo(SUPERVISION_ADMIN)
    }

    @Test
    fun getMostImportantEnforcingAdmin_returnsDpcAdmin() {
        val policyEnforcementInfo = PolicyEnforcementInfo(listOf(SYSTEM_ADMIN, DPC_ADMIN))
        assertThat(policyEnforcementInfo.mostImportantEnforcingAdmin).isEqualTo(DPC_ADMIN)
    }

    companion object {
        private const val PACKAGE_NAME = "package-name"
        private const val PACKAGE_CLASS = "package-name-class"
        private const val SYSTEM_ENTITY = "android-platform"
        private val SYSTEM_USER_HANDLE = UserHandle.SYSTEM
        private val COMPONENT_NAME = ComponentName(PACKAGE_NAME, PACKAGE_CLASS)
        val SUPERVISION_ADMIN =
            android.app.admin.EnforcingAdmin(
                PACKAGE_NAME,
                RoleAuthority(setOf(RoleManager.ROLE_SYSTEM_SUPERVISION)),
                SYSTEM_USER_HANDLE,
                COMPONENT_NAME,
            )
        val DPC_ADMIN =
            android.app.admin.EnforcingAdmin(
                PACKAGE_NAME,
                DpcAuthority.DPC_AUTHORITY,
                SYSTEM_USER_HANDLE,
                COMPONENT_NAME,
            )
        val SYSTEM_ADMIN =
            android.app.admin.EnforcingAdmin(
                PACKAGE_NAME,
                SystemAuthority(SYSTEM_ENTITY),
                SYSTEM_USER_HANDLE,
                null,
            )
    }
}