Merge "Fix Incorrect Trust Agent Count" into tm-qpr-dev
diff --git a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
index 49f94c8..9cc50f4 100644
--- a/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
+++ b/src/com/android/settings/security/trustagent/ManageTrustAgentsPreferenceController.java
@@ -32,12 +32,14 @@
     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 @@
     }
 
     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 f5c693a..c8d403a 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentManager.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentManager.java
@@ -99,13 +99,27 @@
     }
 
     /**
-     * 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 @@
                 }
                 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 72bdd39..dde2f5d 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 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;
@@ -46,6 +46,8 @@
 public class ManageTrustAgentsPreferenceControllerTest {
 
     @Mock
+    private TrustAgentManager mTrustAgentManager;
+    @Mock
     private LockPatternUtils mLockPatternUtils;
 
     private FakeFeatureFactory mFeatureFactory;
@@ -60,6 +62,8 @@
         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 @@
     @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 @@
     @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 7796dc3..8088c7c 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 @@
 
 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.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 @@
 
         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;
+    }
 }