From 6fec2be00dec7f9a40628f300427f73426948f26 Mon Sep 17 00:00:00 2001 From: Derek Jedral Date: Tue, 16 Aug 2022 16:01:10 -0700 Subject: [PATCH] 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 --- ...ManageTrustAgentsPreferenceController.java | 4 +- .../trustagent/TrustAgentManager.java | 25 +++- ...geTrustAgentsPreferenceControllerTest.java | 13 +- .../trustagent/TrustAgentManagerTest.java | 125 +++++++++++++++++- 4 files changed, 157 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java index 49f94c81187..9cc50f4c816 100644 --- a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java +++ b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java @@ -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(); } } diff --git a/src/com/android/settings/security/trustagent/TrustAgentManager.java b/src/com/android/settings/security/trustagent/TrustAgentManager.java index f5c693aba23..c8d403a86e3 100644 --- a/src/com/android/settings/security/trustagent/TrustAgentManager.java +++ b/src/com/android/settings/security/trustagent/TrustAgentManager.java @@ -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 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 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( diff --git a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java index 72bdd399498..dde2f5d17ea 100644 --- a/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceControllerTest.java @@ -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); diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentManagerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentManagerTest.java index 7796dc3d4fb..8088c7c60e0 100644 --- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentManagerTest.java +++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentManagerTest.java @@ -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 resolveInfos = + Collections.singletonList(createResolveInfo(hasSettingsActivity)); + List 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; + } }