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

Commit 6fec2be0 authored by Derek Jedral's avatar Derek Jedral
Browse files

Fix Incorrect Trust Agent Count

The total number of trustagents can still be incorrect if the user
enables a trustagent, and then the trust agent component gets disabled,
since the user does not manually toggle the preference themselves. Fixed
by switching back to the original method of using TrustAgentManager, but
also pass a flag that allows us to choose on whether we want to filter
the trustagents based on whether it has an activity (which not all
trustagents are guaranteed to have).

Bug: 240969157
Test: Local test + atest
Change-Id: I5106859f61ddf36c1bf008da18be889ceaf27a8d
parent bbcdc919
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -32,12 +32,14 @@ public class ManageTrustAgentsPreferenceController extends BasePreferenceControl
    private static final int MY_USER_ID = UserHandle.myUserId();

    private final LockPatternUtils mLockPatternUtils;
    private TrustAgentManager mTrustAgentManager;

    public ManageTrustAgentsPreferenceController(Context context, String key) {
        super(context, key);
        final SecurityFeatureProvider securityFeatureProvider = FeatureFactory.getFactory(context)
                .getSecurityFeatureProvider();
        mLockPatternUtils = securityFeatureProvider.getLockPatternUtils(context);
        mTrustAgentManager = securityFeatureProvider.getTrustAgentManager();
    }

    @Override
@@ -64,6 +66,6 @@ public class ManageTrustAgentsPreferenceController extends BasePreferenceControl
    }

    private int getTrustAgentCount() {
        return mLockPatternUtils.getEnabledTrustAgents(MY_USER_ID).size();
        return mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils, false).size();
    }
}
+21 −4
Original line number Diff line number Diff line
@@ -99,13 +99,27 @@ public class TrustAgentManager {
    }

    /**
     * Returns a list of trust agents.
     * Returns a list of trust agents that have a android:settingsActivity set in their declaration.
     *
     * If {@link #ONLY_ONE_TRUST_AGENT} is set, the list will contain up to 1 agent instead of all
     * available agents on device.
     */
    public List<TrustAgentComponentInfo> getActiveTrustAgents(Context context,
            LockPatternUtils utils) {
        return getActiveTrustAgents(context, utils, true);
    }

    /**
     * Returns a list of trust agents.
     *
     * If {@link #ONLY_ONE_TRUST_AGENT} is set, the list will contain up to 1 agent instead of all
     * available agents on device.
     *
     * @param skipTrustAgentsWithNoActivity {@code false} to only include trustagents with
     * android:settingsActivity set in their declaration, {@code true} otherwise.
     */
    public List<TrustAgentComponentInfo> getActiveTrustAgents(Context context,
            LockPatternUtils utils, boolean skipTrustAgentsWithNoActivity) {
        final int myUserId = UserHandle.myUserId();
        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
        final PackageManager pm = context.getPackageManager();
@@ -125,9 +139,12 @@ public class TrustAgentManager {
                }
                final TrustAgentComponentInfo trustAgentComponentInfo =
                        getSettingsComponent(pm, resolveInfo);
                if (trustAgentComponentInfo.componentName == null ||
                        !enabledTrustAgents.contains(getComponentName(resolveInfo)) ||
                        TextUtils.isEmpty(trustAgentComponentInfo.title)) {
                if (skipTrustAgentsWithNoActivity
                        && trustAgentComponentInfo.componentName == null) {
                    continue;
                }
                if (!enabledTrustAgents.contains(getComponentName(resolveInfo))
                        || TextUtils.isEmpty(trustAgentComponentInfo.title)) {
                    continue;
                }
                if (admin != null && dpm.getTrustAgentConfiguration(
+9 −4
Original line number Diff line number Diff line
@@ -21,13 +21,13 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;

import android.content.ComponentName;
import android.content.Context;

import androidx.preference.Preference;

import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComponentInfo;
import com.android.settings.testutils.FakeFeatureFactory;

import org.junit.Before;
@@ -45,6 +45,8 @@ import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class ManageTrustAgentsPreferenceControllerTest {

    @Mock
    private TrustAgentManager mTrustAgentManager;
    @Mock
    private LockPatternUtils mLockPatternUtils;

@@ -60,6 +62,8 @@ public class ManageTrustAgentsPreferenceControllerTest {
        mFeatureFactory = FakeFeatureFactory.setupForTest();
        when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
                .thenReturn(mLockPatternUtils);
        when(mFeatureFactory.securityFeatureProvider.getTrustAgentManager())
                .thenReturn(mTrustAgentManager);
        mController = new ManageTrustAgentsPreferenceController(mContext, "key");
        mPreference = new Preference(mContext);
        mPreference.setKey(mController.getPreferenceKey());
@@ -90,7 +94,8 @@ public class ManageTrustAgentsPreferenceControllerTest {
    @Test
    public void updateState_isSecure_noTrustAgent_shouldShowGenericSummary() {
        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
        when(mLockPatternUtils.getEnabledTrustAgents(anyInt())).thenReturn(new ArrayList<>());
        when(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils, false))
                .thenReturn(new ArrayList<>());

        mController.updateState(mPreference);

@@ -102,8 +107,8 @@ public class ManageTrustAgentsPreferenceControllerTest {
    @Test
    public void updateState_isSecure_hasTrustAgent_shouldShowDetailedSummary() {
        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
        when(mLockPatternUtils.getEnabledTrustAgents(anyInt())).thenReturn(
                Collections.singletonList(new ComponentName("packageName", "className")));
        when(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils, false))
                .thenReturn(Collections.singletonList(new TrustAgentComponentInfo()));

        mController.updateState(mPreference);

+124 −1
Original line number Diff line number Diff line
@@ -18,11 +18,27 @@ package com.android.settings.security.trustagent;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.when;

import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.os.UserManager;
import android.service.trust.TrustAgentService;

import com.android.internal.widget.LockPatternUtils;

import org.junit.Before;
import org.junit.Test;
@@ -30,21 +46,55 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

@RunWith(RobolectricTestRunner.class)
public class TrustAgentManagerTest {

    private static final String CANNED_PACKAGE_NAME = "com.test.package";
    private static final String CANNED_CLASS_NAME = "TestTrustAgent";
    private static final String CANNED_TRUST_AGENT_TITLE = "TestTrustAgentTitle";

    @Mock
    private PackageManager mPackageManager;
    @Mock
    private Context mContext;
    @Mock
    private DevicePolicyManager mDevicePolicyManager;
    @Mock
    private LockPatternUtils mLockPatternUtils;
    @Mock
    private UserManager mUserManager;
    @Mock
    private UserInfo mUserInfo;
    @Mock
    private XmlResourceParser mXmlResourceParser;
    @Mock
    private Resources mResources;
    @Mock
    private TypedArray mTypedArray;

    private TrustAgentManager mTrustAgentManager;

    @Before
    public void setUp() {
    public void setUp() throws NameNotFoundException {
        MockitoAnnotations.initMocks(this);
        mTrustAgentManager = new TrustAgentManager();
        when(mContext.getSystemService(DevicePolicyManager.class))
                .thenReturn(mDevicePolicyManager);
        when(mContext.getPackageManager()).thenReturn(mPackageManager);
        when(mContext.getSystemService(Context.USER_SERVICE))
                .thenReturn(mUserManager);
        when(mResources.obtainAttributes(any(), any())).thenReturn(mTypedArray);
        when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class)))
                .thenReturn(mResources);
        when(mPackageManager.getXml(any(), anyInt(), any())).thenReturn(mXmlResourceParser);
        when(mUserManager.getUserInfo(anyInt())).thenReturn(mUserInfo);
    }

    @Test
@@ -72,4 +122,77 @@ public class TrustAgentManagerTest {

        assertThat(mTrustAgentManager.shouldProvideTrust(resolveInfo, mPackageManager)).isFalse();
    }

    @Test
    public void getAllActiveTrustAgentsAndComponentSet_returnsTrustAgents()
            throws XmlPullParserException, IOException {
        setUpGetActiveTrustAgents(true);

        assertThat(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils, false))
            .isNotEmpty();
    }

    @Test
    public void getActiveTrustAgentsAndComponentSet_componentSet_returnsTrustAgents()
            throws XmlPullParserException, IOException {
        setUpGetActiveTrustAgents(true);

        assertThat(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils, true))
            .isNotEmpty();
    }

    @Test
    public void getAllActiveTrustAgentsAndComponentNotSet_returnsTrustAgents()
            throws XmlPullParserException, IOException {
        setUpGetActiveTrustAgents(false);

        assertThat(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils, false))
            .isNotEmpty();
    }

    @Test
    public void getActiveTrustAgentsAndComponentSet_returnsEmpty()
            throws XmlPullParserException, IOException {
        setUpGetActiveTrustAgents(false);

        assertThat(mTrustAgentManager.getActiveTrustAgents(mContext, mLockPatternUtils, true))
            .isEmpty();
    }

    private void setUpGetActiveTrustAgents(boolean hasSettingsActivity)
            throws XmlPullParserException, IOException {
        String settingsActivity =
                hasSettingsActivity ? CANNED_PACKAGE_NAME + "." + CANNED_CLASS_NAME : "";
        when(mXmlResourceParser.next()).thenReturn(XmlPullParser.START_TAG);
        when(mXmlResourceParser.getName()).thenReturn("trust-agent");
        List<ResolveInfo> resolveInfos =
                Collections.singletonList(createResolveInfo(hasSettingsActivity));
        List<ComponentName> enabledTrustAgents =
                Collections.singletonList(
                      new ComponentName(CANNED_PACKAGE_NAME, CANNED_CLASS_NAME));

        when(mPackageManager.queryIntentServices(any(), anyInt())).thenReturn(resolveInfos);
        when(mLockPatternUtils.getEnabledTrustAgents(anyInt())).thenReturn(enabledTrustAgents);
        when(mUserInfo.isManagedProfile()).thenReturn(false);
        when(mUserManager.getProfiles(anyInt())).thenReturn(null);
        when(mPackageManager.checkPermission(TrustAgentManager.PERMISSION_PROVIDE_AGENT,
                CANNED_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_GRANTED);
        when(mTypedArray.getString(com.android.internal.R.styleable.TrustAgent_title))
            .thenReturn(CANNED_TRUST_AGENT_TITLE);
        when(mTypedArray.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity))
            .thenReturn(settingsActivity);
    }

    private ResolveInfo createResolveInfo(boolean hasSettingsActivity) {
        ServiceInfo serviceInfo = new ServiceInfo();
        Bundle metaData = new Bundle();
        metaData.putInt(TrustAgentService.TRUST_AGENT_META_DATA, 1);
        serviceInfo.packageName = CANNED_PACKAGE_NAME;
        serviceInfo.name = CANNED_CLASS_NAME;
        serviceInfo.metaData = metaData;
        serviceInfo.applicationInfo = new ApplicationInfo();
        ResolveInfo resolveInfo = new ResolveInfo();
        resolveInfo.serviceInfo = serviceInfo;
        return resolveInfo;
    }
}