Merge "Add a new field showInPersonalTab in AppEntry."
This commit is contained in:
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user