diff options
| author | 2022-09-22 09:20:12 +0000 | |
|---|---|---|
| committer | 2022-11-10 08:00:12 +0000 | |
| commit | 3b658c49e0df20a88a474864f8161e5ce70e63cf (patch) | |
| tree | 83ab450f576858374a5b8ae816b808f41a011a2e | |
| parent | 54716fa8e33c35a3047e27d2bec3284b40ac19c5 (diff) | |
Add a new field showInPersonalTab in AppEntry.
Cloned apps should be displayed in the personal tab only and not in new
tab. Hence modify the personal tab filter to include apps whose user
profile has the property set as
UserPropert.SHOW_IN_SETTINGS_WITH_PARENT. Likewise also mofify the work
tab filter to not display these apps.
Bug: 248204976
Test: manual (verfied with primary, clone and managed profile present on
device at the same time)
Test: make RunSettingsLibRoboTests -j40 ROBOTEST_FILTER=ApplicationsStateRoboTest
Test: atest ApplicationsStateTest
Change-Id: I619f2bfe65837e30bfbcdecd43314f735d03b321
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(); + } } |