diff --git a/res/xml/trust_agent_settings.xml b/res/xml/trust_agent_settings.xml
index 2bf71fb028c..c6539c4fde9 100644
--- a/res/xml/trust_agent_settings.xml
+++ b/res/xml/trust_agent_settings.xml
@@ -14,11 +14,10 @@
limitations under the License.
-->
-
-
-
-
+ android:title="@string/manage_trust_agents"
+ settings:controller="com.android.settings.security.trustagent.TrustAgentsPreferenceController">
diff --git a/src/com/android/settings/security/trustagent/TrustAgentInfo.java b/src/com/android/settings/security/trustagent/TrustAgentInfo.java
new file mode 100644
index 00000000000..f8198021273
--- /dev/null
+++ b/src/com/android/settings/security/trustagent/TrustAgentInfo.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 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.settings.security.trustagent;
+
+import android.content.ComponentName;
+import android.graphics.drawable.Drawable;
+
+public class TrustAgentInfo implements Comparable {
+ private final CharSequence mLabel;
+ private final ComponentName mComponentName;
+ private final Drawable mIcon;
+
+ public TrustAgentInfo(CharSequence label, ComponentName componentName, Drawable icon) {
+ mLabel = label;
+ mComponentName = componentName;
+ mIcon = icon;
+ }
+
+ public CharSequence getLabel() {
+ return mLabel;
+ }
+
+ public ComponentName getComponentName() {
+ return mComponentName;
+ }
+
+ public Drawable getIcon() {
+ return mIcon;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof TrustAgentInfo) {
+ return mComponentName.equals(((TrustAgentInfo) other).getComponentName());
+ }
+ return false;
+ }
+
+ @Override
+ public int compareTo(TrustAgentInfo other) {
+ return mComponentName.compareTo(other.getComponentName());
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/settings/security/trustagent/TrustAgentSettings.java b/src/com/android/settings/security/trustagent/TrustAgentSettings.java
index 02d354a78fd..11d23418731 100644
--- a/src/com/android/settings/security/trustagent/TrustAgentSettings.java
+++ b/src/com/android/settings/security/trustagent/TrustAgentSettings.java
@@ -16,62 +16,22 @@
package com.android.settings.security.trustagent;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.service.trust.TrustAgentService;
-import androidx.preference.SwitchPreference;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceGroup;
-import android.util.ArrayMap;
-import android.util.ArraySet;
+import android.provider.SearchIndexableResource;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.widget.LockPatternUtils;
import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settingslib.search.SearchIndexable;
+import java.util.ArrayList;
import java.util.List;
-public class TrustAgentSettings extends SettingsPreferenceFragment implements
- Preference.OnPreferenceChangeListener {
- private static final String SERVICE_INTERFACE = TrustAgentService.SERVICE_INTERFACE;
-
- private ArrayMap mAvailableAgents;
- private final ArraySet mActiveAgents = new ArraySet();
- private LockPatternUtils mLockPatternUtils;
- private DevicePolicyManager mDpm;
- private TrustAgentManager mTrustAgentManager;
-
- public static final class AgentInfo {
- CharSequence label;
- ComponentName component; // service that implements ITrustAgent
- SwitchPreference preference;
- public Drawable icon;
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof AgentInfo) {
- return component.equals(((AgentInfo)other).component);
- }
- return true;
- }
-
- public int compareTo(AgentInfo other) {
- return component.compareTo(other.component);
- }
- }
+@SearchIndexable
+public class TrustAgentSettings extends DashboardFragment {
+ private static final String TAG = "TrustAgentSettings";
@Override
public int getMetricsCategory() {
@@ -84,122 +44,25 @@ public class TrustAgentSettings extends SettingsPreferenceFragment implements
}
@Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- mDpm = getActivity().getSystemService(DevicePolicyManager.class);
- mTrustAgentManager =
- FeatureFactory.getFactory(getActivity()).getSecurityFeatureProvider()
- .getTrustAgentManager();
-
- addPreferencesFromResource(R.xml.trust_agent_settings);
- }
-
- public void onResume() {
- super.onResume();
- removePreference("dummy_preference");
- updateAgents();
- }
-
- private void updateAgents() {
- final Context context = getActivity();
- if (mAvailableAgents == null) {
- mAvailableAgents = findAvailableTrustAgents();
- }
- if (mLockPatternUtils == null) {
- mLockPatternUtils = new LockPatternUtils(getActivity());
- }
- loadActiveAgents();
- PreferenceGroup category =
- (PreferenceGroup) getPreferenceScreen().findPreference("trust_agents");
- category.removeAll();
-
- final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(context,
- DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
-
- final int count = mAvailableAgents.size();
- for (int i = 0; i < count; i++) {
- AgentInfo agent = mAvailableAgents.valueAt(i);
- final RestrictedSwitchPreference preference =
- new RestrictedSwitchPreference(getPrefContext());
- preference.useAdminDisabledSummary(true);
- agent.preference = preference;
- preference.setPersistent(false);
- preference.setTitle(agent.label);
- preference.setIcon(agent.icon);
- preference.setPersistent(false);
- preference.setOnPreferenceChangeListener(this);
- preference.setChecked(mActiveAgents.contains(agent.component));
-
- if (admin != null
- && mDpm.getTrustAgentConfiguration(null, agent.component) == null) {
- preference.setChecked(false);
- preference.setDisabledByAdmin(admin);
- }
-
- category.addPreference(agent.preference);
- }
- }
-
- private void loadActiveAgents() {
- List activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents(
- UserHandle.myUserId());
- if (activeTrustAgents != null) {
- mActiveAgents.addAll(activeTrustAgents);
- }
- }
-
- private void saveActiveAgents() {
- mLockPatternUtils.setEnabledTrustAgents(mActiveAgents,
- UserHandle.myUserId());
- }
-
- private ArrayMap findAvailableTrustAgents() {
- PackageManager pm = getActivity().getPackageManager();
- Intent trustAgentIntent = new Intent(SERVICE_INTERFACE);
- List resolveInfos = pm.queryIntentServices(trustAgentIntent,
- PackageManager.GET_META_DATA);
-
- ArrayMap agents = new ArrayMap();
- final int count = resolveInfos.size();
- agents.ensureCapacity(count);
- for (int i = 0; i < count; i++ ) {
- ResolveInfo resolveInfo = resolveInfos.get(i);
- if (resolveInfo.serviceInfo == null) {
- continue;
- }
- if (!mTrustAgentManager.shouldProvideTrust(resolveInfo, pm)) {
- continue;
- }
- ComponentName name = mTrustAgentManager.getComponentName(resolveInfo);
- AgentInfo agentInfo = new AgentInfo();
- agentInfo.label = resolveInfo.loadLabel(pm);
- agentInfo.icon = resolveInfo.loadIcon(pm);
- agentInfo.component = name;
- agents.put(name, agentInfo);
- }
- return agents;
+ protected String getLogTag() {
+ return TAG;
}
@Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference instanceof SwitchPreference) {
- final int count = mAvailableAgents.size();
- for (int i = 0; i < count; i++) {
- AgentInfo agent = mAvailableAgents.valueAt(i);
- if (agent.preference == preference) {
- if ((Boolean) newValue) {
- if (!mActiveAgents.contains(agent.component)) {
- mActiveAgents.add(agent.component);
- }
- } else {
- mActiveAgents.remove(agent.component);
- }
- saveActiveAgents();
- return true;
- }
- }
- }
- return false;
+ protected int getPreferenceScreenResId() {
+ return R.xml.trust_agent_settings;
}
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List getXmlResourcesToIndex(
+ Context context, boolean enabled) {
+ final List result = new ArrayList<>();
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.trust_agent_settings;
+ result.add(sir);
+ return result;
+ }
+ };
}
diff --git a/src/com/android/settings/security/trustagent/TrustAgentsPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentsPreferenceController.java
new file mode 100644
index 00000000000..604583b33e7
--- /dev/null
+++ b/src/com/android/settings/security/trustagent/TrustAgentsPreferenceController.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2018 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.settings.security.trustagent;
+
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import android.service.trust.TrustAgentService;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.IconDrawableFactory;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.security.SecurityFeatureProvider;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnStart;
+
+import java.util.List;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.SwitchPreference;
+
+public class TrustAgentsPreferenceController extends BasePreferenceController
+ implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart {
+
+ private static final Intent TRUST_AGENT_INTENT =
+ new Intent(TrustAgentService.SERVICE_INTERFACE);
+
+ private final ArrayMap mAvailableAgents;
+ private final ArraySet mActiveAgents;
+ private final DevicePolicyManager mDevicePolicyManager;
+ private final IconDrawableFactory mIconDrawableFactory;
+ private final LockPatternUtils mLockPatternUtils;
+ private final PackageManager mPackageManager;
+ private final TrustAgentManager mTrustAgentManager;
+
+ private PreferenceScreen mScreen;
+
+ public TrustAgentsPreferenceController(Context context, String key) {
+ super(context, key);
+ mAvailableAgents = new ArrayMap<>();
+ mActiveAgents = new ArraySet<>();
+ mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
+ mIconDrawableFactory = IconDrawableFactory.newInstance(context);
+ final SecurityFeatureProvider securityFeatureProvider =
+ FeatureFactory.getFactory(context).getSecurityFeatureProvider();
+ mTrustAgentManager = securityFeatureProvider.getTrustAgentManager();
+ mLockPatternUtils = securityFeatureProvider.getLockPatternUtils(context);
+ mPackageManager = context.getPackageManager();
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mScreen = screen;
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+
+ @Override
+ public void onStart() {
+ updateAgents();
+ }
+
+ private void updateAgents() {
+ findAvailableTrustAgents();
+ loadActiveAgents();
+ removeUselessExistingPreferences();
+
+ final EnforcedAdmin admin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled(mContext,
+ DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS, UserHandle.myUserId());
+
+ for (TrustAgentInfo agent : mAvailableAgents.values()) {
+ final ComponentName componentName = agent.getComponentName();
+ RestrictedSwitchPreference preference = (RestrictedSwitchPreference)
+ mScreen.findPreference(componentName.flattenToString());
+ if (preference == null) {
+ preference = new RestrictedSwitchPreference(mScreen.getContext());
+ }
+ preference.setKey(componentName.flattenToString());
+ preference.useAdminDisabledSummary(true);
+ preference.setTitle(agent.getLabel());
+ preference.setIcon(agent.getIcon());
+ preference.setOnPreferenceChangeListener(this);
+ preference.setChecked(mActiveAgents.contains(componentName));
+ if (admin != null && mDevicePolicyManager.getTrustAgentConfiguration(null /* admin */,
+ componentName) == null) {
+ preference.setChecked(false);
+ preference.setDisabledByAdmin(admin);
+ }
+ mScreen.addPreference(preference);
+ }
+ }
+
+ private void loadActiveAgents() {
+ final List activeTrustAgents = mLockPatternUtils.getEnabledTrustAgents(
+ UserHandle.myUserId());
+ if (activeTrustAgents != null) {
+ mActiveAgents.addAll(activeTrustAgents);
+ }
+ }
+
+ private void saveActiveAgents() {
+ mLockPatternUtils.setEnabledTrustAgents(mActiveAgents, UserHandle.myUserId());
+ }
+
+ private void findAvailableTrustAgents() {
+ final List resolveInfos = mPackageManager.queryIntentServices(
+ TRUST_AGENT_INTENT, PackageManager.GET_META_DATA);
+ mAvailableAgents.clear();
+ for (ResolveInfo resolveInfo : resolveInfos) {
+ if (resolveInfo.serviceInfo == null) {
+ continue;
+ }
+ if (!mTrustAgentManager.shouldProvideTrust(resolveInfo, mPackageManager)) {
+ continue;
+ }
+ final CharSequence label = resolveInfo.loadLabel(mPackageManager);
+ final ComponentName componentName = mTrustAgentManager.getComponentName(resolveInfo);
+ final Drawable icon = mIconDrawableFactory.getBadgedIcon(
+ resolveInfo.getComponentInfo().applicationInfo);
+ final TrustAgentInfo agentInfo = new TrustAgentInfo(label, componentName, icon);
+ mAvailableAgents.put(componentName, agentInfo);
+ }
+ }
+
+ private void removeUselessExistingPreferences() {
+ final int count = mScreen.getPreferenceCount();
+ if (count <= 0) {
+ return;
+ }
+ for (int i = count - 1; i >= 0; i--) {
+ final Preference pref = mScreen.getPreference(i);
+ final String[] names = TextUtils.split(pref.getKey(), "/");
+ final ComponentName componentName = new ComponentName(names[0], names[1]);
+ if (!mAvailableAgents.containsKey(componentName)) {
+ mScreen.removePreference(pref);
+ mActiveAgents.remove(componentName);
+ }
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (!(preference instanceof SwitchPreference)) {
+ return false;
+ }
+ for (TrustAgentInfo agent : mAvailableAgents.values()) {
+ final ComponentName componentName = agent.getComponentName();
+ if (!TextUtils.equals(preference.getKey(), componentName.flattenToString())) {
+ continue;
+ }
+ if ((Boolean) newValue && !mActiveAgents.contains(componentName)) {
+ mActiveAgents.add(componentName);
+ } else {
+ mActiveAgents.remove(componentName);
+ }
+ saveActiveAgents();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable
index 9e8952e92de..8523b2f1ab9 100644
--- a/tests/robotests/assets/grandfather_not_implementing_indexable
+++ b/tests/robotests/assets/grandfather_not_implementing_indexable
@@ -57,7 +57,6 @@ com.android.settings.network.ApnSettings
com.android.settings.wifi.calling.WifiCallingSettingsForSub
com.android.settings.password.SetupChooseLockGeneric$SetupChooseLockGenericFragment
com.android.settings.SetupRedactionInterstitial$SetupRedactionInterstitialFragment
-com.android.settings.security.trustagent.TrustAgentSettings
com.android.settings.password.ChooseLockGeneric$ChooseLockGenericFragment
com.android.settings.IccLockSettings
com.android.settings.TetherSettings
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
index 94298be696d..6be834b8871 100644
--- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java
@@ -16,8 +16,10 @@
package com.android.settings.security.trustagent;
-import static com.android.settings.security.trustagent.TrustAgentListPreferenceController.PREF_KEY_SECURITY_CATEGORY;
-import static com.android.settings.security.trustagent.TrustAgentListPreferenceController.PREF_KEY_TRUST_AGENT;
+import static com.android.settings.security.trustagent.TrustAgentListPreferenceController
+ .PREF_KEY_SECURITY_CATEGORY;
+import static com.android.settings.security.trustagent.TrustAgentListPreferenceController
+ .PREF_KEY_TRUST_AGENT;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeastOnce;
@@ -27,12 +29,8 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
-import androidx.lifecycle.LifecycleOwner;
import android.content.ComponentName;
import android.content.Context;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceScreen;
import com.android.internal.widget.LockPatternUtils;
import com.android.settings.core.PreferenceControllerMixin;
@@ -52,6 +50,11 @@ import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
@RunWith(SettingsRobolectricTestRunner.class)
public class TrustAgentListPreferenceControllerTest {
@@ -81,9 +84,9 @@ public class TrustAgentListPreferenceControllerTest {
mLifecycle = new Lifecycle(mLifecycleOwner);
mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(any(Context.class)))
- .thenReturn(mLockPatternUtils);
+ .thenReturn(mLockPatternUtils);
when(mFeatureFactory.securityFeatureProvider.getTrustAgentManager())
- .thenReturn(mTrustAgentManager);
+ .thenReturn(mTrustAgentManager);
when(mCategory.getKey()).thenReturn(PREF_KEY_SECURITY_CATEGORY);
when(mCategory.getContext()).thenReturn(mActivity);
when(mScreen.findPreference(PREF_KEY_SECURITY_CATEGORY)).thenReturn(mCategory);
@@ -121,14 +124,14 @@ public class TrustAgentListPreferenceControllerTest {
public void onResume_shouldAddNewAgents() {
final List agents = new ArrayList<>();
final TrustAgentManager.TrustAgentComponentInfo agent =
- mock(TrustAgentManager.TrustAgentComponentInfo.class);
+ mock(TrustAgentManager.TrustAgentComponentInfo.class);
agent.title = "Test_title";
agent.summary = "test summary";
agent.componentName = new ComponentName("pkg", "agent");
agent.admin = null;
agents.add(agent);
when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils))
- .thenReturn(agents);
+ .thenReturn(agents);
mController.displayPreference(mScreen);
mController.onResume();
@@ -141,7 +144,7 @@ public class TrustAgentListPreferenceControllerTest {
public void onResume_ifNotAvailable_shouldNotAddNewAgents() {
final List agents = new ArrayList<>();
final TrustAgentManager.TrustAgentComponentInfo agent =
- mock(TrustAgentManager.TrustAgentComponentInfo.class);
+ mock(TrustAgentManager.TrustAgentComponentInfo.class);
agent.title = "Test_title";
agent.summary = "test summary";
agent.componentName = new ComponentName("pkg", "agent");
diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
new file mode 100644
index 00000000000..43a80018cc5
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentsPreferenceControllerTest.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2018 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.settings.security.trustagent;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.service.trust.TrustAgentService;
+
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowDevicePolicyManager;
+import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
+import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowApplicationPackageManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {
+ ShadowLockPatternUtils.class,
+ ShadowRestrictedLockUtils.class,
+ ShadowDevicePolicyManager.class,
+ ShadowApplicationPackageManager.class,
+ TrustAgentsPreferenceControllerTest.ShadowTrustAgentManager.class
+})
+public class TrustAgentsPreferenceControllerTest {
+
+ private static final Intent TEST_INTENT =
+ new Intent(TrustAgentService.SERVICE_INTERFACE);
+
+ private Context mContext;
+ private ShadowApplicationPackageManager mPackageManager;
+ private TrustAgentsPreferenceController mController;
+ private PreferenceManager mPreferenceManager;
+ private PreferenceScreen mPreferenceScreen;
+
+ @Before
+ public void setUp() {
+ mContext = RuntimeEnvironment.application;
+ mPackageManager = (ShadowApplicationPackageManager) Shadows.shadowOf(
+ mContext.getPackageManager());
+ mController = new TrustAgentsPreferenceController(mContext, "pref_key");
+ mPreferenceManager = new PreferenceManager(mContext);
+ mPreferenceScreen = mPreferenceManager.createPreferenceScreen(mContext);
+ mPreferenceScreen.setKey("pref_key");
+ }
+
+ @After
+ public void tearDown() {
+ ShadowTrustAgentManager.clearPermissionGrantedList();
+ }
+
+ @Test
+ public void getAvailabilityStatus_byDefault_shouldBeShown() {
+ assertThat(mController.getAvailabilityStatus())
+ .isEqualTo(BasePreferenceController.AVAILABLE);
+ }
+
+ @Test
+ public void onStart_noTrustAgent_shouldNotAddPreference() {
+ final List availableAgents = createFakeAvailableAgents();
+ mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+
+ mController.displayPreference(mPreferenceScreen);
+ mController.onStart();
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(0);
+ }
+
+ @Test
+ public void
+ onStart_hasAUninstalledTrustAgent_shouldRemoveOnePreferenceAndLeaveTwoPreferences() {
+ final List availableAgents = createFakeAvailableAgents();
+ final ResolveInfo uninstalledTrustAgent = availableAgents.get(0);
+ for (ResolveInfo rInfo : availableAgents) {
+ ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
+ }
+ mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mController.displayPreference(mPreferenceScreen);
+ mController.onStart();
+ availableAgents.remove(uninstalledTrustAgent);
+
+ mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mController.onStart();
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(2);
+ }
+
+ @Test
+ public void onStart_hasANewTrustAgent_shouldAddOnePreferenceAndHaveFourPreferences() {
+ final List availableAgents = createFakeAvailableAgents();
+ final ComponentName newComponentName = new ComponentName("test.data.packageD", "clzDDD");
+ final ResolveInfo newTrustAgent = createFakeResolveInfo(newComponentName);
+ for (ResolveInfo rInfo : availableAgents) {
+ ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
+ }
+ mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mController.displayPreference(mPreferenceScreen);
+ mController.onStart();
+ availableAgents.add(newTrustAgent);
+ ShadowTrustAgentManager.grantPermissionToResolveInfo(newTrustAgent);
+
+ mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ mController.onStart();
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(4);
+ }
+
+ @Test
+ public void onStart_hasUnrestrictedTrustAgent_shouldAddThreeChangeablePreferences() {
+ ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(0);
+ final List availableAgents = createFakeAvailableAgents();
+ for (ResolveInfo rInfo : availableAgents) {
+ ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
+ }
+ mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+
+ mController.displayPreference(mPreferenceScreen);
+ mController.onStart();
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(3);
+ for (int i = 0; i < mPreferenceScreen.getPreferenceCount(); i++) {
+ RestrictedSwitchPreference preference =
+ (RestrictedSwitchPreference) mPreferenceScreen.getPreference(i);
+ assertThat(preference.isDisabledByAdmin()).isFalse();
+ }
+ }
+
+ @Test
+ public void onStart_hasRestrictedTructAgent_shouldAddThreeUnchangeablePreferences() {
+ final List availableAgents = createFakeAvailableAgents();
+ for (ResolveInfo rInfo : availableAgents) {
+ ShadowTrustAgentManager.grantPermissionToResolveInfo(rInfo);
+ }
+ mPackageManager.addResolveInfoForIntent(TEST_INTENT, availableAgents);
+ ShadowRestrictedLockUtils.setKeyguardDisabledFeatures(
+ DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS);
+
+ mController.displayPreference(mPreferenceScreen);
+ mController.onStart();
+
+ assertThat(mPreferenceScreen.getPreferenceCount()).isEqualTo(3);
+ for (int i = 0; i < mPreferenceScreen.getPreferenceCount(); i++) {
+ RestrictedSwitchPreference preference =
+ (RestrictedSwitchPreference) mPreferenceScreen.getPreference(i);
+ assertThat(preference.isDisabledByAdmin()).isTrue();
+ }
+ }
+
+ private List createFakeAvailableAgents() {
+ final List componentNames = new ArrayList<>();
+ componentNames.add(new ComponentName("test.data.packageA", "clzAAA"));
+ componentNames.add(new ComponentName("test.data.packageB", "clzBBB"));
+ componentNames.add(new ComponentName("test.data.packageC", "clzCCC"));
+ final List result = new ArrayList<>();
+ for (ComponentName cn : componentNames) {
+ final ResolveInfo ri = createFakeResolveInfo(cn);
+ result.add(ri);
+ }
+ return result;
+ }
+
+ private ResolveInfo createFakeResolveInfo(ComponentName cn) {
+ final ResolveInfo ri = new ResolveInfo();
+ ri.serviceInfo = new ServiceInfo();
+ ri.serviceInfo.packageName = cn.getPackageName();
+ ri.serviceInfo.name = cn.getClassName();
+ ri.serviceInfo.applicationInfo = new ApplicationInfo();
+ ri.serviceInfo.applicationInfo.packageName = cn.getPackageName();
+ ri.serviceInfo.applicationInfo.name = cn.getClassName();
+ return ri;
+ }
+
+ @Implements(TrustAgentManager.class)
+ public static class ShadowTrustAgentManager {
+ private final static List sPermissionGrantedList = new ArrayList<>();
+
+ @Implementation
+ public boolean shouldProvideTrust(ResolveInfo resolveInfo, PackageManager pm) {
+ if (sPermissionGrantedList.contains(resolveInfo)) {
+ return true;
+ }
+ return false;
+ }
+
+ public static void grantPermissionToResolveInfo(ResolveInfo rInfo) {
+ sPermissionGrantedList.add(rInfo);
+ }
+
+ public static void clearPermissionGrantedList() {
+ sPermissionGrantedList.clear();
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java
index 16ef69981fc..b4e64924628 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java
@@ -5,6 +5,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
+import android.os.PersistableBundle;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
@@ -12,6 +13,7 @@ import org.robolectric.annotation.Implements;
import org.robolectric.shadow.api.Shadow;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -75,4 +77,10 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev
return (ShadowDevicePolicyManager) Shadow.extract(
RuntimeEnvironment.application.getSystemService(DevicePolicyManager.class));
}
+
+ public @Nullable
+ List getTrustAgentConfiguration(
+ @Nullable ComponentName admin, @NonNull ComponentName agent) {
+ return null;
+ }
}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
index e7f6be5f743..86276689b57 100644
--- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowLockPatternUtils.java
@@ -17,12 +17,15 @@
package com.android.settings.testutils.shadow;
import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
import com.android.internal.widget.LockPatternUtils;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import java.util.List;
+
@Implements(LockPatternUtils.class)
public class ShadowLockPatternUtils {
@@ -49,6 +52,11 @@ public class ShadowLockPatternUtils {
return sDeviceEncryptionEnabled;
}
+ @Implementation
+ public List getEnabledTrustAgents(int userId) {
+ return null;
+ }
+
public static void setDeviceEncryptionEnabled(boolean deviceEncryptionEnabled) {
sDeviceEncryptionEnabled = deviceEncryptionEnabled;
}