Allow some packages to be excluded during during work profile creation.
Bug: 31657192
Test: adb shell am instrument -e class com.android.server.pm.UserManagerTest#testAddManagedProfile_withDisallowedPackages -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
Change-Id: I37eab6084e0f911d0e2407186b789875588194a2
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index df02b86..6e87558 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -20618,9 +20618,9 @@
}
/** Called by UserManagerService */
- void createNewUser(int userId) {
+ void createNewUser(int userId, String[] disallowedPackages) {
synchronized (mInstallLock) {
- mSettings.createNewUserLI(this, mInstaller, userId);
+ mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
}
synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(userId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8cab355..ba1dde0 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3956,7 +3956,7 @@
}
void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
- int userHandle) {
+ int userHandle, String[] disallowedPackages) {
String[] volumeUuids;
String[] names;
int[] appIds;
@@ -3977,8 +3977,10 @@
if (ps.pkg == null || ps.pkg.applicationInfo == null) {
continue;
}
+ final boolean shouldInstall = ps.isSystem() &&
+ !ArrayUtils.contains(disallowedPackages, ps.name);
// Only system apps are initially installed.
- ps.setInstalled(ps.isSystem(), userHandle);
+ ps.setInstalled(shouldInstall, userHandle);
// Need to create a data directory for all apps under this user. Accumulate all
// required args and call the installer after mPackages lock has been released
volumeUuids[i] = ps.volumeUuid;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 533d9b5..9146bec2 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2182,9 +2182,10 @@
}
@Override
- public UserInfo createProfileForUser(String name, int flags, int userId) {
+ public UserInfo createProfileForUser(String name, int flags, int userId,
+ String[] disallowedPackages) {
checkManageOrCreateUsersPermission(flags);
- return createUserInternal(name, flags, userId);
+ return createUserInternal(name, flags, userId, disallowedPackages);
}
@Override
@@ -2194,6 +2195,11 @@
}
private UserInfo createUserInternal(String name, int flags, int parentId) {
+ return createUserInternal(name, flags, parentId, null);
+ }
+
+ private UserInfo createUserInternal(String name, int flags, int parentId,
+ String[] disallowedPackages) {
if (hasUserRestriction(UserManager.DISALLOW_ADD_USER, UserHandle.getCallingUserId())) {
Log.w(LOG_TAG, "Cannot add user. DISALLOW_ADD_USER is enabled.");
return null;
@@ -2204,10 +2210,11 @@
Log.w(LOG_TAG, "Cannot add user. Not enough space on disk.");
return null;
}
- return createUserInternalUnchecked(name, flags, parentId);
+ return createUserInternalUnchecked(name, flags, parentId, disallowedPackages);
}
- private UserInfo createUserInternalUnchecked(String name, int flags, int parentId) {
+ private UserInfo createUserInternalUnchecked(String name, int flags, int parentId,
+ String[] disallowedPackages) {
if (ActivityManager.isLowRamDeviceStatic()) {
return null;
}
@@ -2321,7 +2328,7 @@
storage.createUserKey(userId, userInfo.serialNumber, userInfo.isEphemeral());
mPm.prepareUserData(userId, userInfo.serialNumber,
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
- mPm.createNewUser(userId);
+ mPm.createNewUser(userId, disallowedPackages);
userInfo.partial = false;
synchronized (mPackagesLock) {
writeUserLP(userData);
@@ -2371,7 +2378,8 @@
@Override
public UserInfo createRestrictedProfile(String name, int parentUserId) {
checkManageOrCreateUsersPermission("setupRestrictedProfile");
- final UserInfo user = createProfileForUser(name, UserInfo.FLAG_RESTRICTED, parentUserId);
+ final UserInfo user = createProfileForUser(
+ name, UserInfo.FLAG_RESTRICTED, parentUserId, null);
if (user == null) {
return null;
}
@@ -3533,7 +3541,7 @@
@Override
public UserInfo createUserEvenWhenDisallowed(String name, int flags) {
- UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL);
+ UserInfo user = createUserInternalUnchecked(name, flags, UserHandle.USER_NULL, null);
// Keep this in sync with UserManager.createUser
if (user != null && !user.isAdmin()) {
setUserRestriction(UserManager.DISALLOW_SMS, true, user.id);
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 514f095..3548f28 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -44,6 +44,7 @@
<uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
<uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+ <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 6a434ca..0fb2c9f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.app.ActivityManager;
import android.os.Bundle;
@@ -46,16 +47,24 @@
private static final int REMOVE_TIMEOUT_MILLIS = 60 * 1000; // 60 seconds
private static final int SWITCH_USER_TIMEOUT_MILLIS = 40 * 1000; // 40 seconds
+ // Packages which are used during tests.
+ private static final String[] PACKAGES = new String[] {
+ "com.android.egg",
+ "com.android.retaildemo"
+ };
+
private final Object mUserRemoveLock = new Object();
private final Object mUserSwitchLock = new Object();
private UserManager mUserManager = null;
+ private PackageManager mPackageManager;
private List<Integer> usersToRemove;
@Override
public void setUp() throws Exception {
super.setUp();
mUserManager = UserManager.get(getContext());
+ mPackageManager = getContext().getPackageManager();
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED);
filter.addAction(Intent.ACTION_USER_SWITCHED);
@@ -185,6 +194,49 @@
assertFalse(mUserManager.isManagedProfile());
}
+ // Verify that disallowed packages are not installed in the managed profile.
+ @MediumTest
+ public void testAddManagedProfile_withDisallowedPackages() throws Exception {
+ final int primaryUserId = mUserManager.getPrimaryUser().id;
+ UserInfo userInfo1 = createProfileForUser("Managed1",
+ UserInfo.FLAG_MANAGED_PROFILE, primaryUserId);
+ // Verify that the packagesToVerify are installed by default.
+ for (String pkg : PACKAGES) {
+ assertTrue("Package should be installed in managed profile: " + pkg,
+ isPackageInstalledForUser(pkg, userInfo1.id));
+ }
+ removeUser(userInfo1.id);
+
+ UserInfo userInfo2 = createProfileForUser("Managed2",
+ UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
+ // Verify that the packagesToVerify are not installed by default.
+ for (String pkg : PACKAGES) {
+ assertFalse("Package should not be installed in managed profile when disallowed: "
+ + pkg, isPackageInstalledForUser(pkg, userInfo2.id));
+ }
+ }
+
+ // Verify that if any packages are disallowed to install during creation of managed profile can
+ // still be installed later.
+ @MediumTest
+ public void testAddManagedProfile_disallowedPackagesInstalledLater() throws Exception {
+ final int primaryUserId = mUserManager.getPrimaryUser().id;
+ UserInfo userInfo = createProfileForUser("Managed",
+ UserInfo.FLAG_MANAGED_PROFILE, primaryUserId, PACKAGES);
+ // Verify that the packagesToVerify are not installed by default.
+ for (String pkg : PACKAGES) {
+ assertFalse("Package should not be installed in managed profile when disallowed: "
+ + pkg, isPackageInstalledForUser(pkg, userInfo.id));
+ }
+
+ // Verify that the disallowed packages during profile creation can be installed now.
+ for (String pkg : PACKAGES) {
+ assertEquals("Package could not be installed: " + pkg,
+ PackageManager.INSTALL_SUCCEEDED,
+ mPackageManager.installExistingPackageAsUser(pkg, userInfo.id));
+ }
+ }
+
@MediumTest
public void testAddRestrictedProfile() throws Exception {
UserInfo userInfo = createRestrictedProfile("Profile");
@@ -357,6 +409,14 @@
switchUser(startUser);
}
+ private boolean isPackageInstalledForUser(String packageName, int userId) {
+ try {
+ return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null;
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ }
+ }
+
private void switchUser(int userId) {
synchronized (mUserSwitchLock) {
ActivityManager am = getContext().getSystemService(ActivityManager.class);
@@ -401,7 +461,13 @@
}
private UserInfo createProfileForUser(String name, int flags, int userHandle) {
- UserInfo profile = mUserManager.createProfileForUser(name, flags, userHandle);
+ return createProfileForUser(name, flags, userHandle, null);
+ }
+
+ private UserInfo createProfileForUser(String name, int flags, int userHandle,
+ String[] disallowedPackages) {
+ UserInfo profile = mUserManager.createProfileForUser(
+ name, flags, userHandle, disallowedPackages);
if (profile != null) {
usersToRemove.add(profile.id);
}