From 8311f680657ec7dcea4a938e97f2acaea1940f12 Mon Sep 17 00:00:00 2001 From: Adam Bookatz Date: Wed, 27 Apr 2022 12:24:24 -0700 Subject: [PATCH] Fix Settings getProfileIdsWithDisabled usage In two places, Settings uses getProfileIdsWithDisabled intending to restrict itself to *managed* profiles, but actually allows for any type of profile. Since the declared intent is to only deal with managed profiles, we update the code to only consider managed profiles. On devices that only have managed profiles (currently almost all devices), this cl is a no-op. Bug: 230495929 Bug: 230534572 Bug: 170249807 Test: com.android.settings.UtilsTest Test: make RunSettingsRoboTests -j Change-Id: Id04d45839ef61080b00ca2f91525718cb3a85120 --- src/com/android/settings/Utils.java | 28 +++++++++---------- ...edactNotificationPreferenceController.java | 15 ++++++---- .../AppStateNotificationBridgeTest.java | 21 ++++++-------- ...ProfileStatusPreferenceControllerTest.java | 6 +++- ...ectedServicesPreferenceControllerTest.java | 4 +++ ...tNotificationPreferenceControllerTest.java | 13 ++++++--- ...atternProfilePreferenceControllerTest.java | 7 ++++- 7 files changed, 57 insertions(+), 37 deletions(-) diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 2988ddcaedb..990667e537e 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -85,7 +85,6 @@ import android.text.TextUtils; import android.text.format.DateUtils; import android.text.style.TtsSpan; import android.util.ArraySet; -import android.util.FeatureFlagUtils; import android.util.IconDrawableFactory; import android.util.Log; import android.view.LayoutInflater; @@ -435,18 +434,20 @@ public final class Utils extends com.android.settingslib.Utils { * {@link #getManagedProfile} this method returns enabled and disabled managed profiles. */ public static UserHandle getManagedProfileWithDisabled(UserManager userManager) { - // TODO: Call getManagedProfileId from here once Robolectric supports - // API level 24 and UserManager.getProfileIdsWithDisabled can be Mocked (to avoid having - // yet another implementation that loops over user profiles in this method). In the meantime - // we need to use UserManager.getProfiles that is available on API 23 (the one currently - // used for Settings Robolectric tests). - final int myUserId = UserHandle.myUserId(); - final List profiles = userManager.getProfiles(myUserId); + return getManagedProfileWithDisabled(userManager, UserHandle.myUserId()); + } + + /** + * Returns the managed profile of the given user or {@code null} if none is found. Unlike + * {@link #getManagedProfile} this method returns enabled and disabled managed profiles. + */ + private static UserHandle getManagedProfileWithDisabled(UserManager um, int parentUserId) { + final List profiles = um.getProfiles(parentUserId); final int count = profiles.size(); for (int i = 0; i < count; i++) { final UserInfo profile = profiles.get(i); if (profile.isManagedProfile() - && profile.getUserHandle().getIdentifier() != myUserId) { + && profile.getUserHandle().getIdentifier() != parentUserId) { return profile.getUserHandle(); } } @@ -455,15 +456,14 @@ public final class Utils extends com.android.settingslib.Utils { /** * Retrieves the id for the given user's managed profile. + * Unlike {@link #getManagedProfile} this method returns enabled and disabled managed profiles. * * @return the managed profile id or UserHandle.USER_NULL if there is none. */ public static int getManagedProfileId(UserManager um, int parentUserId) { - final int[] profileIds = um.getProfileIdsWithDisabled(parentUserId); - for (int profileId : profileIds) { - if (profileId != parentUserId) { - return profileId; - } + final UserHandle profile = getManagedProfileWithDisabled(um, parentUserId); + if (profile != null) { + return profile.getIdentifier(); } return UserHandle.USER_NULL; } diff --git a/src/com/android/settings/notification/RedactNotificationPreferenceController.java b/src/com/android/settings/notification/RedactNotificationPreferenceController.java index 2d2718478c2..0b9ad4413ce 100644 --- a/src/com/android/settings/notification/RedactNotificationPreferenceController.java +++ b/src/com/android/settings/notification/RedactNotificationPreferenceController.java @@ -22,6 +22,7 @@ import static android.provider.Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFIC import android.app.KeyguardManager; import android.content.Context; +import android.content.pm.UserInfo; import android.database.ContentObserver; import android.os.Handler; import android.os.Looper; @@ -42,6 +43,8 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; +import java.util.List; + /** * The controller of the sensitive notifications. */ @@ -74,11 +77,13 @@ public class RedactNotificationPreferenceController extends TogglePreferenceCont mKm = context.getSystemService(KeyguardManager.class); mProfileUserId = UserHandle.myUserId(); - final int[] profileIds = mUm.getProfileIdsWithDisabled(UserHandle.myUserId()); - - for (int profileId : profileIds) { - if (profileId != UserHandle.myUserId()) { - mProfileUserId = profileId; + final List profiles = mUm.getProfiles(UserHandle.myUserId()); + final int count = profiles.size(); + for (int i = 0; i < count; i++) { + final UserInfo profile = profiles.get(i); + if (profile.isManagedProfile() + && profile.getUserHandle().getIdentifier() != UserHandle.myUserId()) { + mProfileUserId = profile.getUserHandle().getIdentifier(); } } } diff --git a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java index b725fc30c02..61dd569cf52 100644 --- a/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java +++ b/tests/robotests/src/com/android/settings/applications/AppStateNotificationBridgeTest.java @@ -18,16 +18,11 @@ package com.android.settings.applications; import static android.text.format.DateUtils.DAY_IN_MILLIS; -import static com.android.settings.applications.AppStateNotificationBridge - .FILTER_APP_NOTIFICATION_BLOCKED; -import static com.android.settings.applications.AppStateNotificationBridge - .FILTER_APP_NOTIFICATION_FREQUENCY; -import static com.android.settings.applications.AppStateNotificationBridge - .FILTER_APP_NOTIFICATION_RECENCY; -import static com.android.settings.applications.AppStateNotificationBridge - .FREQUENCY_NOTIFICATION_COMPARATOR; -import static com.android.settings.applications.AppStateNotificationBridge - .RECENT_NOTIFICATION_COMPARATOR; +import static com.android.settings.applications.AppStateNotificationBridge.FILTER_APP_NOTIFICATION_BLOCKED; +import static com.android.settings.applications.AppStateNotificationBridge.FILTER_APP_NOTIFICATION_FREQUENCY; +import static com.android.settings.applications.AppStateNotificationBridge.FILTER_APP_NOTIFICATION_RECENCY; +import static com.android.settings.applications.AppStateNotificationBridge.FREQUENCY_NOTIFICATION_COMPARATOR; +import static com.android.settings.applications.AppStateNotificationBridge.RECENT_NOTIFICATION_COMPARATOR; import static com.google.common.truth.Truth.assertThat; @@ -47,12 +42,12 @@ import android.app.usage.UsageEvents; import android.app.usage.UsageEvents.Event; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.UserInfo; import android.os.Looper; import android.os.Parcel; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; -import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.Switch; @@ -71,6 +66,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -288,7 +284,8 @@ public class AppStateNotificationBridgeTest { @Test public void testLoadAllExtraInfo_multipleUsers() throws RemoteException { // has work profile - when(mUserManager.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[]{1}); + when(mUserManager.getProfiles(anyInt())).thenReturn(Arrays.asList( + new UserInfo(1, "", UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE))); mBridge = new AppStateNotificationBridge(mContext, mState, mock(AppStateBaseBridge.Callback.class), mUsageStats, mUserManager, mBackend); diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintProfileStatusPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintProfileStatusPreferenceControllerTest.java index efcba9d9584..0988795dd10 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintProfileStatusPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintProfileStatusPreferenceControllerTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.PackageManager; +import android.content.pm.UserInfo; import android.hardware.fingerprint.FingerprintManager; import android.os.UserManager; @@ -39,6 +40,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.shadows.ShadowApplication; +import java.util.Arrays; + @RunWith(RobolectricTestRunner.class) public class FingerprintProfileStatusPreferenceControllerTest { @@ -71,7 +74,8 @@ public class FingerprintProfileStatusPreferenceControllerTest { mFeatureFactory = FakeFeatureFactory.setupForTest(); when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext)) .thenReturn(mLockPatternUtils); - when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {1234}); + when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList( + new UserInfo(1234, "", UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE))); mController = new FingerprintProfileStatusPreferenceController(mContext, TEST_PREF_KEY); } diff --git a/tests/robotests/src/com/android/settings/location/LocationInjectedServicesPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationInjectedServicesPreferenceControllerTest.java index ae62724cea5..bed3346ffba 100644 --- a/tests/robotests/src/com/android/settings/location/LocationInjectedServicesPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/location/LocationInjectedServicesPreferenceControllerTest.java @@ -28,6 +28,7 @@ import static org.mockito.Mockito.when; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; +import android.content.pm.UserInfo; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -118,6 +119,9 @@ public class LocationInjectedServicesPreferenceControllerTest { final int fakeWorkProfileId = 123; ShadowUserManager.getShadow().setProfileIdsWithDisabled( new int[]{UserHandle.myUserId(), fakeWorkProfileId}); + ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0)); + ShadowUserManager.getShadow().addProfile(new UserInfo(fakeWorkProfileId, "", + UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE)); // Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return non-null. final List enforcingUsers = new ArrayList<>(); diff --git a/tests/robotests/src/com/android/settings/notification/RedactNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RedactNotificationPreferenceControllerTest.java index 72a2c2451ee..8304d82be9f 100644 --- a/tests/robotests/src/com/android/settings/notification/RedactNotificationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/RedactNotificationPreferenceControllerTest.java @@ -34,11 +34,11 @@ import static org.mockito.Mockito.when; import android.app.KeyguardManager; import android.app.admin.DevicePolicyManager; import android.content.Context; +import android.content.pm.UserInfo; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.internal.widget.LockPatternUtils; @@ -57,6 +57,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import java.util.Arrays; + @RunWith(RobolectricTestRunner.class) @Config(shadows = { ShadowUtils.class, @@ -95,7 +97,7 @@ public class RedactNotificationPreferenceControllerTest { when(mMockContext.getSystemService(UserManager.class)).thenReturn(mUm); when(mMockContext.getSystemService(DevicePolicyManager.class)).thenReturn(mDpm); when(mMockContext.getSystemService(KeyguardManager.class)).thenReturn(mKm); - when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {0}); + when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList(new UserInfo(0, "", 0))); mController = new RedactNotificationPreferenceController( mMockContext, RedactNotificationPreferenceController.KEY_LOCKSCREEN_REDACT); @@ -105,7 +107,9 @@ public class RedactNotificationPreferenceControllerTest { mController.getPreferenceKey())).thenReturn(mPreference); assertThat(mController.mProfileUserId).isEqualTo(0); - when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {0, 10}); + when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList( + new UserInfo(5, "", 0), + new UserInfo(10, "", UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE))); mWorkController = new RedactNotificationPreferenceController(mMockContext, RedactNotificationPreferenceController.KEY_LOCKSCREEN_WORK_PROFILE_REDACT); mWorkPreference = new RestrictedSwitchPreference(mContext); @@ -137,7 +141,8 @@ public class RedactNotificationPreferenceControllerTest { @Test public void getAvailabilityStatus_noWorkProfile() { // reset controllers with no work profile - when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {UserHandle.myUserId()}); + when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList( + new UserInfo(UserHandle.myUserId(), "", 0))); mWorkController = new RedactNotificationPreferenceController(mMockContext, RedactNotificationPreferenceController.KEY_LOCKSCREEN_WORK_PROFILE_REDACT); mController = new RedactNotificationPreferenceController(mMockContext, diff --git a/tests/robotests/src/com/android/settings/security/VisiblePatternProfilePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/VisiblePatternProfilePreferenceControllerTest.java index 11d70165794..ba50eb85992 100644 --- a/tests/robotests/src/com/android/settings/security/VisiblePatternProfilePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/VisiblePatternProfilePreferenceControllerTest.java @@ -31,6 +31,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.PackageManager; +import android.content.pm.UserInfo; import android.hardware.fingerprint.FingerprintManager; import android.os.UserManager; @@ -49,6 +50,8 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.shadows.ShadowApplication; +import java.util.Arrays; + @RunWith(RobolectricTestRunner.class) public class VisiblePatternProfilePreferenceControllerTest { @@ -82,7 +85,9 @@ public class VisiblePatternProfilePreferenceControllerTest { mFeatureFactory = FakeFeatureFactory.setupForTest(); when(mFeatureFactory.securityFeatureProvider.getLockPatternUtils(mContext)) .thenReturn(mLockPatternUtils); - when(mUm.getProfileIdsWithDisabled(anyInt())).thenReturn(new int[] {FAKE_PROFILE_USER_ID}); + when(mUm.getProfiles(anyInt())).thenReturn(Arrays.asList(new UserInfo( + FAKE_PROFILE_USER_ID, "", UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE))); + mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner);