summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java2
-rw-r--r--core/java/android/os/IUserManager.aidl3
-rw-r--r--core/java/android/os/UserManager.java27
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java4
-rw-r--r--services/core/java/com/android/server/pm/Settings.java6
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java22
-rw-r--r--services/tests/servicestests/AndroidManifest.xml1
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java68
8 files changed, 115 insertions, 18 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index ace4e3284930..ac8ee8d38c3f 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -981,7 +981,7 @@ public final class Pm {
} else if (userId < 0) {
info = mUm.createUser(name, flags);
} else {
- info = mUm.createProfileForUser(name, flags, userId);
+ info = mUm.createProfileForUser(name, flags, userId, null);
}
if (info != null) {
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index eeb641d33c20..3324f6fe4589 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -36,7 +36,8 @@ interface IUserManager {
int getCredentialOwnerProfile(int userHandle);
UserInfo createUser(in String name, int flags);
- UserInfo createProfileForUser(in String name, int flags, int userHandle);
+ UserInfo createProfileForUser(in String name, int flags, int userHandle,
+ in String[] disallowedPackages);
UserInfo createRestrictedProfile(String name, int parentUserHandle);
void setUserEnabled(int userHandle);
boolean removeUser(int userHandle);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 5dc18fb117ef..c7e5e6308a8a 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1340,15 +1340,34 @@ public class UserManager {
*
* @param name the user's name
* @param flags flags that identify the type of user and other properties.
- * @see UserInfo
- * @param userHandle new user will be a profile of this use.
+ * @param userHandle new user will be a profile of this user.
*
- * @return the UserInfo object for the created user, or null if the user could not be created.
+ * @return the {@link UserInfo} object for the created user, or null if the user
+ * could not be created.
* @hide
*/
public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userHandle) {
+ return createProfileForUser(name, flags, userHandle, null);
+ }
+
+ /**
+ * Version of {@link #createProfileForUser(String, int, int)} that allows you to specify
+ * any packages that should not be installed in the new profile by default, these packages can
+ * still be installed later by the user if needed.
+ *
+ * @param name the user's name
+ * @param flags flags that identify the type of user and other properties.
+ * @param userHandle new user will be a profile of this user.
+ * @param disallowedPackages packages that will not be installed in the profile being created.
+ *
+ * @return the {@link UserInfo} object for the created user, or null if the user
+ * could not be created.
+ * @hide
+ */
+ public UserInfo createProfileForUser(String name, int flags, @UserIdInt int userHandle,
+ String[] disallowedPackages) {
try {
- return mService.createProfileForUser(name, flags, userHandle);
+ return mService.createProfileForUser(name, flags, userHandle, disallowedPackages);
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index df02b86956cc..6e87558324c4 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 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
}
/** 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 8cab355dc3bd..ba1dde0d9467 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 @@ final class Settings {
}
void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
- int userHandle) {
+ int userHandle, String[] disallowedPackages) {
String[] volumeUuids;
String[] names;
int[] appIds;
@@ -3977,8 +3977,10 @@ final class Settings {
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 533d9b5b6c73..9146bec2af49 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 @@ public class UserManagerService extends IUserManager.Stub {
}
@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 @@ public class UserManagerService extends IUserManager.Stub {
}
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 @@ public class UserManagerService extends IUserManager.Stub {
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 @@ public class UserManagerService extends IUserManager.Stub {
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 @@ public class UserManagerService extends IUserManager.Stub {
@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 @@ public class UserManagerService extends IUserManager.Stub {
@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 514f095cbd58..3548f28ec52e 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 6a434ca4d3fc..0fb2c9fb28dc 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.BroadcastReceiver;
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 @@ public class UserManagerTest extends AndroidTestCase {
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 @@ public class UserManagerTest extends AndroidTestCase {
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 @@ public class UserManagerTest extends AndroidTestCase {
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 @@ public class UserManagerTest extends AndroidTestCase {
}
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);
}