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
This commit is contained in:
“Ankita
2022-09-22 09:20:12 +00:00
parent 54716fa8e3
commit 3b658c49e0
3 changed files with 104 additions and 3 deletions

View File

@@ -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;
}
};

View File

@@ -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();
}
}

View File

@@ -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();
}
}