diff options
3 files changed, 104 insertions, 3 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index 7913c16b6b98..65c94cec6009 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -36,8 +36,10 @@ import android.content.pm.PackageStats; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; +import android.content.pm.UserProperties; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -1577,8 +1579,8 @@ public class ApplicationsState { public long internalSize; public long externalSize; public String labelDescription; - public boolean mounted; + public boolean showInPersonalTab; /** * Setting this to {@code true} prevents the entry to be filtered by @@ -1635,6 +1637,33 @@ public class ApplicationsState { ThreadUtils.postOnBackgroundThread( () -> this.ensureLabelDescriptionLocked(context)); } + this.showInPersonalTab = shouldShowInPersonalTab(context, info.uid); + } + + /** + * Checks if the user that the app belongs to have the property + * {@link UserProperties#SHOW_IN_SETTINGS_WITH_PARENT} set. + */ + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + boolean shouldShowInPersonalTab(Context context, int uid) { + UserManager userManager = UserManager.get(context); + int userId = UserHandle.getUserId(uid); + + // Regardless of apk version, if the app belongs to the current user then return true. + if (userId == ActivityManager.getCurrentUser()) { + return true; + } + + // For sdk version < 34, if the app doesn't belong to the current user, + // then as per earlier behaviour the app shouldn't be displayed in personal tab. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + return false; + } + + UserProperties userProperties = userManager.getUserProperties( + UserHandle.of(userId)); + return userProperties.getShowInSettings() + == UserProperties.SHOW_IN_SETTINGS_WITH_PARENT; } public void ensureLabel(Context context) { @@ -1784,7 +1813,7 @@ public class ApplicationsState { @Override public boolean filterApp(AppEntry entry) { - return UserHandle.getUserId(entry.info.uid) == mCurrentUser; + return entry.showInPersonalTab; } }; @@ -1811,7 +1840,7 @@ public class ApplicationsState { @Override public boolean filterApp(AppEntry entry) { - return UserHandle.getUserId(entry.info.uid) != mCurrentUser; + return !entry.showInPersonalTab; } }; diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java index f1e1e7d920cc..c5598bfa9438 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/applications/ApplicationsStateTest.java @@ -293,4 +293,15 @@ public class ApplicationsStateTest { assertThat(ApplicationsState.FILTER_MOVIES.filterApp(mEntry)).isFalse(); } + + @Test + public void testPersonalAndWorkFiltersDisplaysCorrectApps() { + mEntry.showInPersonalTab = true; + assertThat(ApplicationsState.FILTER_PERSONAL.filterApp(mEntry)).isTrue(); + assertThat(ApplicationsState.FILTER_WORK.filterApp(mEntry)).isFalse(); + + mEntry.showInPersonalTab = false; + assertThat(ApplicationsState.FILTER_PERSONAL.filterApp(mEntry)).isFalse(); + assertThat(ApplicationsState.FILTER_WORK.filterApp(mEntry)).isTrue(); + } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java index fc2bf0a9bd93..39875f7950e4 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ApplicationsStateRoboTest.java @@ -17,6 +17,7 @@ package com.android.settingslib.applications; import static android.os.UserHandle.MU_ENABLED; +import static android.os.UserHandle.USER_SYSTEM; import static com.google.common.truth.Truth.assertThat; @@ -48,9 +49,11 @@ import android.content.pm.ModuleInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; +import android.content.pm.UserProperties; import android.content.res.Resources; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; @@ -58,6 +61,8 @@ import android.os.UserManager; import android.text.TextUtils; import android.util.IconDrawableFactory; +import androidx.test.core.app.ApplicationProvider; + import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.ApplicationsState.Callbacks; import com.android.settingslib.applications.ApplicationsState.Session; @@ -71,6 +76,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.Spy; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -79,6 +85,7 @@ import org.robolectric.annotation.Implements; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowContextImpl; import org.robolectric.shadows.ShadowLooper; +import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.Arrays; @@ -95,6 +102,7 @@ public class ApplicationsStateRoboTest { private final static String LAUNCHABLE_PACKAGE_NAME = "com.android.launchable"; private static final int PROFILE_USERID = 10; + private static final int PROFILE_USERID2 = 11; private static final String PKG_1 = "PKG1"; private static final int OWNER_UID_1 = 1001; @@ -106,6 +114,10 @@ public class ApplicationsStateRoboTest { private static final String PKG_3 = "PKG3"; private static final int OWNER_UID_3 = 1003; + private static final int PROFILE_UID_3 = UserHandle.getUid(PROFILE_USERID2, OWNER_UID_3); + + private static final String CLONE_USER = "clone_user"; + private static final String RANDOM_USER = "random_user"; /** Class under test */ private ApplicationsState mApplicationsState; @@ -113,6 +125,8 @@ public class ApplicationsStateRoboTest { private Application mApplication; + @Spy + Context mContext = ApplicationProvider.getApplicationContext(); @Mock private Callbacks mCallbacks; @Captor @@ -738,4 +752,51 @@ public class ApplicationsStateRoboTest { when(configChanges.applyNewConfig(any(Resources.class))).thenReturn(false); mApplicationsState.setInterestingConfigChanges(configChanges); } + + @Test + public void shouldShowInPersonalTab_forCurrentUser_returnsTrue() { + ApplicationInfo appInfo = createApplicationInfo(PKG_1); + AppEntry primaryUserApp = createAppEntry(appInfo, 1); + + assertThat(primaryUserApp.shouldShowInPersonalTab(mContext, appInfo.uid)).isTrue(); + } + + @Test + public void shouldShowInPersonalTab_userProfilePreU_returnsFalse() { + ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", + Build.VERSION_CODES.TIRAMISU); + // Create an app (and subsequent AppEntry) in a non-primary user profile. + ApplicationInfo appInfo1 = createApplicationInfo(PKG_1, PROFILE_UID_1); + AppEntry nonPrimaryUserApp = createAppEntry(appInfo1, 1); + + assertThat(nonPrimaryUserApp.shouldShowInPersonalTab(mContext, appInfo1.uid)).isFalse(); + } + + @Test + public void shouldShowInPersonalTab_currentUserIsParent_returnsAsPerUserPropertyOfProfile1() { + // Mark system user as parent for both profile users. + ShadowUserManager shadowUserManager = Shadow + .extract(RuntimeEnvironment.application.getSystemService(UserManager.class)); + shadowUserManager.addProfile(USER_SYSTEM, PROFILE_USERID, + CLONE_USER, 0); + shadowUserManager.addProfile(USER_SYSTEM, PROFILE_USERID2, + RANDOM_USER, 0); + shadowUserManager.setupUserProperty(PROFILE_USERID, + /*showInSettings*/ UserProperties.SHOW_IN_SETTINGS_WITH_PARENT); + shadowUserManager.setupUserProperty(PROFILE_USERID2, + /*showInSettings*/ UserProperties.SHOW_IN_SETTINGS_NO); + + ReflectionHelpers.setStaticField(Build.VERSION.class, "SDK_INT", + Build.VERSION_CODES.UPSIDE_DOWN_CAKE); + + // Treat PROFILE_USERID as a clone user profile and create an app PKG_1 in it. + ApplicationInfo appInfo1 = createApplicationInfo(PKG_1, PROFILE_UID_1); + // Treat PROFILE_USERID2 as a random non-primary profile and create an app PKG_3 in it. + ApplicationInfo appInfo2 = createApplicationInfo(PKG_3, PROFILE_UID_3); + AppEntry nonPrimaryUserApp1 = createAppEntry(appInfo1, 1); + AppEntry nonPrimaryUserApp2 = createAppEntry(appInfo2, 2); + + assertThat(nonPrimaryUserApp1.shouldShowInPersonalTab(mContext, appInfo1.uid)).isTrue(); + assertThat(nonPrimaryUserApp2.shouldShowInPersonalTab(mContext, appInfo2.uid)).isFalse(); + } } |