From ee6c4bacd8ad842d688de534269a43830a10c766 Mon Sep 17 00:00:00 2001 From: Billy Huang Date: Tue, 27 Feb 2024 15:12:39 -0800 Subject: [PATCH] Use disabled summary when trustagents are disabled This makes trust agent preferences follow the behavior of other features that can be disabled by device admins, otherwise the preference is simply greyed out without context until the user clicks on the preference. Bug: 319095039 Test: Covered by TrustAgentListPreferenceControllerTest#onResume_restrictedPreferenceShouldUseAdminDisabledSummary Test: atest SettingsRoboTests:com.android.settings.security --host Test: manually validated that disabled admin policy results in showing "Controlled by admin" as the summary Flag: EXEMPT bugfix for single preference in settings Change-Id: I89f052cf2479a120d8b5b223414162f129cde89e --- .../TrustAgentListPreferenceController.java | 7 +- ...rustAgentListPreferenceControllerTest.java | 130 +++++++++++++----- 2 files changed, 100 insertions(+), 37 deletions(-) diff --git a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java index 2ec90de9f8a..cd1cb122a34 100644 --- a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java +++ b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; +import android.text.TextUtils; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; @@ -216,7 +217,11 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro trustAgentPreference.setIntent(new Intent(Intent.ACTION_MAIN) .setComponent(agent.componentName)); trustAgentPreference.setDisabledByAdmin(agent.admin); - if (!trustAgentPreference.isDisabledByAdmin() && !hasSecurity) { + if (trustAgentPreference.isDisabledByAdmin()) { + // Ensure visibility by setting non-empty summary text. + trustAgentPreference.setSummary(TextUtils.firstNotEmpty(agent.summary, " ")); + trustAgentPreference.useAdminDisabledSummary(true); + } else if (!trustAgentPreference.isDisabledByAdmin() && !hasSecurity) { trustAgentPreference.setEnabled(false); trustAgentPreference.setSummary(R.string.disabled_because_no_backup_security); } 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 0463e003ae2..5a1d94aca3d 100644 --- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java @@ -23,27 +23,39 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static java.util.Objects.requireNonNull; + import android.app.Activity; import android.content.ComponentName; import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.lifecycle.LifecycleOwner; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; +import androidx.preference.PreferenceViewHolder; import com.android.internal.widget.LockPatternUtils; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.security.SecuritySettings; +import com.android.settings.security.trustagent.TrustAgentManager.TrustAgentComponentInfo; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; +import com.android.settingslib.RestrictedPreference; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.search.SearchIndexableRaw; +import com.google.common.collect.Maps; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,6 +67,7 @@ import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.List; +import java.util.Map; @RunWith(RobolectricTestRunner.class) public class TrustAgentListPreferenceControllerTest { @@ -114,13 +127,8 @@ public class TrustAgentListPreferenceControllerTest { when(mCategory.findPreference(PREF_KEY_TRUST_AGENT + 0)) .thenReturn(oldAgent) .thenReturn(null); - final List agents = new ArrayList<>(); - final TrustAgentManager.TrustAgentComponentInfo agent = - mock(TrustAgentManager.TrustAgentComponentInfo.class); - agent.title = "Test_title"; - agent.summary = "test summary"; - agent.componentName = new ComponentName("pkg", "agent"); - agent.admin = null; + final List agents = new ArrayList<>(); + final TrustAgentComponentInfo agent = createTrustAgentComponentInfo(null); agents.add(agent); when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) .thenReturn(agents); @@ -133,13 +141,8 @@ public class TrustAgentListPreferenceControllerTest { @Test public void onResume_shouldAddNewAgents() { - final List agents = new ArrayList<>(); - final TrustAgentManager.TrustAgentComponentInfo agent = - mock(TrustAgentManager.TrustAgentComponentInfo.class); - agent.title = "Test_title"; - agent.summary = "test summary"; - agent.componentName = new ComponentName("pkg", "agent"); - agent.admin = null; + final List agents = new ArrayList<>(); + final TrustAgentComponentInfo agent = createTrustAgentComponentInfo(null); agents.add(agent); when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) .thenReturn(agents); @@ -153,13 +156,8 @@ public class TrustAgentListPreferenceControllerTest { @Test @Config(qualifiers = "mcc999") public void onResume_ifNotAvailable_shouldNotAddNewAgents() { - final List agents = new ArrayList<>(); - final TrustAgentManager.TrustAgentComponentInfo agent = - mock(TrustAgentManager.TrustAgentComponentInfo.class); - agent.title = "Test_title"; - agent.summary = "test summary"; - agent.componentName = new ComponentName("pkg", "agent"); - agent.admin = null; + final List agents = new ArrayList<>(); + final TrustAgentComponentInfo agent = createTrustAgentComponentInfo(null); agents.add(agent); when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) .thenReturn(agents); @@ -172,13 +170,8 @@ public class TrustAgentListPreferenceControllerTest { @Test public void onResume_controllerShouldHasKey() { - final List agents = new ArrayList<>(); - final TrustAgentManager.TrustAgentComponentInfo agent = - mock(TrustAgentManager.TrustAgentComponentInfo.class); - agent.title = "Test_title"; - agent.summary = "test summary"; - agent.componentName = new ComponentName("pkg", "agent"); - agent.admin = null; + final List agents = new ArrayList<>(); + final TrustAgentComponentInfo agent = createTrustAgentComponentInfo(null); agents.add(agent); when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) .thenReturn(agents); @@ -190,15 +183,69 @@ public class TrustAgentListPreferenceControllerTest { assertThat(mController.mTrustAgentsKeyList).containsExactly(key); } + @Test + public void onResume_shouldShowDisabledByAdminRestrictedPreference() { + final List agents = new ArrayList<>(); + final TrustAgentComponentInfo agent = createTrustAgentComponentInfo(new EnforcedAdmin()); + final Map preferences = setUpPreferenceMap(); + agents.add(agent); + when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) + .thenReturn(agents); + + mController.displayPreference(mScreen); + mController.onResume(); + + assertThat(preferences).hasSize(1); + Preference preference = preferences.values().iterator().next(); + assertThat(preference).isInstanceOf(RestrictedPreference.class); + RestrictedPreference restrictedPreference = (RestrictedPreference) preference; + assertThat(restrictedPreference.isDisabledByAdmin()).isTrue(); + } + + @Test + public void onResume_restrictedPreferenceShouldUseAdminDisabledSummary() { + final List agents = new ArrayList<>(); + final TrustAgentComponentInfo agent = createTrustAgentComponentInfo(new EnforcedAdmin()); + final Map preferences = setUpPreferenceMap(); + final LayoutInflater inflater = LayoutInflater.from(mActivity); + agents.add(agent); + when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) + .thenReturn(agents); + mController.displayPreference(mScreen); + mController.onResume(); + final RestrictedPreference restrictedPreference = + (RestrictedPreference) preferences.values().iterator().next(); + final PreferenceViewHolder viewHolder = PreferenceViewHolder.createInstanceForTests( + inflater.inflate(restrictedPreference.getLayoutResource(), null)); + + restrictedPreference.onBindViewHolder(viewHolder); + + final TextView summaryView = (TextView) requireNonNull( + viewHolder.findViewById(android.R.id.summary)); + assertThat(summaryView.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(summaryView.getText().toString()).isEqualTo( + mActivity.getString( + com.android.settingslib.R.string.disabled_by_admin_summary_text)); + } + + private Map setUpPreferenceMap() { + final Map preferences = Maps.newLinkedHashMap(); + when(mCategory.addPreference(any())).thenAnswer((invocation) -> { + Preference preference = invocation.getArgument(0); + preferences.put(preference.getKey(), preference); + return true; + }); + when(mCategory.removePreference(any())).thenAnswer((invocation) -> { + Preference preference = invocation.getArgument(0); + return preferences.remove(preference.getKey()) != null; + }); + return preferences; + } + @Test public void updateDynamicRawDataToIndex_shouldIndexAgents() { - final List agents = new ArrayList<>(); - final TrustAgentManager.TrustAgentComponentInfo agent = - mock(TrustAgentManager.TrustAgentComponentInfo.class); - agent.title = "Test_title"; - agent.summary = "test summary"; - agent.componentName = new ComponentName("pkg", "agent"); - agent.admin = null; + final List agents = new ArrayList<>(); + final TrustAgentComponentInfo agent = createTrustAgentComponentInfo(null); agents.add(agent); when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) .thenReturn(agents); @@ -208,4 +255,15 @@ public class TrustAgentListPreferenceControllerTest { assertThat(indexRaws).hasSize(1); } + + @NonNull + private static TrustAgentComponentInfo createTrustAgentComponentInfo( + @Nullable EnforcedAdmin admin) { + final TrustAgentComponentInfo agent = new TrustAgentComponentInfo(); + agent.title = "Test_title"; + agent.summary = "test summary"; + agent.componentName = new ComponentName("pkg", "agent"); + agent.admin = admin; + return agent; + } }