summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java21
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl1
-rw-r--r--core/java/android/os/IUserManager.aidl2
-rw-r--r--core/java/android/os/UserManager.java12
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java29
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java85
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java25
8 files changed, 149 insertions, 35 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index db08a41..d7170e8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1816,6 +1816,27 @@ public class DevicePolicyManager {
/**
* @hide
+ * @param userId the userId of a managed profile profile.
+ *
+ * @return whether or not the managed profile is enabled.
+ * @throws IllegalArgumentException if the userId is invalid.
+ */
+ public boolean isProfileEnabled(int userId) throws IllegalArgumentException {
+ if (mService != null) {
+ try {
+ return mService.isProfileEnabled(userId);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Failed to get status for owner profile.");
+ throw new IllegalArgumentException(
+ "Failed to get status for owner profile.", re);
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * @hide
* @return the human readable name of the organisation associated with this DPM or null if
* one is not set.
* @throws IllegalArgumentException if the userId is invalid.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 4ed85e9..85ba58b 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -109,6 +109,7 @@ interface IDevicePolicyManager {
String getProfileOwner(int userHandle);
String getProfileOwnerName(int userHandle);
void setProfileEnabled(in ComponentName who);
+ boolean isProfileEnabled(int userHandle);
boolean installCaCert(in byte[] certBuffer);
void uninstallCaCert(in byte[] certBuffer);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 1192a45..c3f7370 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -34,7 +34,7 @@ interface IUserManager {
void setUserIcon(int userHandle, in Bitmap icon);
Bitmap getUserIcon(int userHandle);
List<UserInfo> getUsers(boolean excludeDying);
- List<UserInfo> getProfiles(int userHandle);
+ List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
UserInfo getUserInfo(int userHandle);
boolean isRestricted();
void setGuestEnabled(boolean enable);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7bac3af..63de9a0 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -466,6 +466,8 @@ public class UserManager {
/**
* Returns list of the profiles of userHandle including
* userHandle itself.
+ * Note that it this returns both enabled and not enabled profiles. See
+ * {@link #getUserProfiles()} if you need only the enabled ones.
*
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
* @param userHandle profiles of this user will be returned.
@@ -474,7 +476,7 @@ public class UserManager {
*/
public List<UserInfo> getProfiles(int userHandle) {
try {
- return mService.getProfiles(userHandle);
+ return mService.getProfiles(userHandle, false /* enabledOnly */);
} catch (RemoteException re) {
Log.w(TAG, "Could not get user list", re);
return null;
@@ -488,7 +490,13 @@ public class UserManager {
*/
public List<UserHandle> getUserProfiles() {
ArrayList<UserHandle> profiles = new ArrayList<UserHandle>();
- List<UserInfo> users = getProfiles(UserHandle.myUserId());
+ List<UserInfo> users = new ArrayList<UserInfo>();
+ try {
+ users = mService.getProfiles(UserHandle.myUserId(), true /* enabledOnly */);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not get user list", re);
+ return null;
+ }
for (UserInfo info : users) {
UserHandle userHandle = new UserHandle(info.id);
profiles.add(userHandle);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8fa076b..ed007e9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -16369,7 +16369,8 @@ public final class ActivityManagerService extends ActivityManagerNative
* background.
*/
private void updateCurrentProfileIdsLocked() {
- final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
+ final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
+ mCurrentUserId, false /* enabledOnly */);
int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
for (int i = 0; i < currentProfileIds.length; i++) {
currentProfileIds[i] = profiles.get(i).id;
@@ -16379,7 +16380,8 @@ public final class ActivityManagerService extends ActivityManagerNative
private Set getProfileIdsLocked(int userId) {
Set userIds = new HashSet<Integer>();
- final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId);
+ final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
+ userId, false /* enabledOnly */);
for (UserInfo user : profiles) {
userIds.add(Integer.valueOf(user.id));
}
@@ -16678,7 +16680,8 @@ public final class ActivityManagerService extends ActivityManagerNative
void startProfilesLocked() {
if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
- List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId);
+ List<UserInfo> profiles = getUserManagerLocked().getProfiles(
+ mCurrentUserId, false /* enabledOnly */);
List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
for (UserInfo user : profiles) {
if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 53db9ef..210e151 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -24,6 +24,7 @@ import android.app.ActivityManagerNative;
import android.app.ActivityThread;
import android.app.admin.DevicePolicyManager;
import android.app.IStopUserCallback;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -258,11 +259,20 @@ public class UserManagerService extends IUserManager.Stub {
}
@Override
- public List<UserInfo> getProfiles(int userId) {
+ public List<UserInfo> getProfiles(int userId, boolean enabledOnly) {
if (userId != UserHandle.getCallingUserId()) {
checkManageUsersPermission("getting profiles related to user " + userId);
}
synchronized (mPackagesLock) {
+ // Getting the service here is not good for testing purposes. However, this service
+ // is not available when UserManagerService starts up so we need a lazy load.
+
+ DevicePolicyManager dpm = null;
+ if (enabledOnly) {
+ dpm = (DevicePolicyManager)
+ mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+ }
+
UserInfo user = getUserInfoLocked(userId);
ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
for (int i = 0; i < mUsers.size(); i++) {
@@ -270,6 +280,23 @@ public class UserManagerService extends IUserManager.Stub {
if (!isProfileOf(user, profile)) {
continue;
}
+
+ if (enabledOnly && profile.isManagedProfile()) {
+ if (dpm != null) {
+ if(!dpm.isProfileEnabled(profile.id)) {
+ continue;
+ }
+ } else {
+ Log.w(LOG_TAG,
+ "Attempting to reach DevicePolicyManager before it was started");
+ // TODO: There might be system apps that need to call this. Make sure that
+ // DevicePolicyManagerService is ready at that time (otherwise, any default
+ // value is a bad one).
+ throw new IllegalArgumentException(String.format(
+ "Attempting to get enabled profiles for %d before "
+ + "DevicePolicyManagerService has been started.", userId));
+ }
+ }
users.add(profile);
}
return users;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index 1b048a1..3186527 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -53,6 +53,7 @@ public class DeviceOwner {
private static final String ATTR_NAME = "name";
private static final String ATTR_PACKAGE = "package";
private static final String ATTR_USERID = "userId";
+ private static final String ATTR_ENABLED = "profileEnabled";
private AtomicFile fileForWriting;
@@ -61,11 +62,10 @@ public class DeviceOwner {
private OutputStream mOutputStreamForTest;
// Internal state for the device owner package.
- private String mDeviceOwnerPackageName;
- private String mDeviceOwnerName;
+ private OwnerInfo mDeviceOwner;
// Internal state for the profile owner packages.
- private final HashMap<Integer, String[]> mProfileOwners = new HashMap<Integer, String[]>();
+ private final HashMap<Integer, OwnerInfo> mProfileOwners = new HashMap<Integer, OwnerInfo>();
// Private default constructor.
private DeviceOwner() {
@@ -95,8 +95,7 @@ public class DeviceOwner {
*/
static DeviceOwner createWithDeviceOwner(String packageName, String ownerName) {
DeviceOwner owner = new DeviceOwner();
- owner.mDeviceOwnerPackageName = packageName;
- owner.mDeviceOwnerName = ownerName;
+ owner.mDeviceOwner = new OwnerInfo(ownerName, packageName);
return owner;
}
@@ -105,25 +104,25 @@ public class DeviceOwner {
*/
static DeviceOwner createWithProfileOwner(String packageName, String ownerName, int userId) {
DeviceOwner owner = new DeviceOwner();
- owner.mProfileOwners.put(userId, new String[] { packageName, ownerName });
+ owner.mProfileOwners.put(
+ userId, new OwnerInfo(ownerName, packageName, false /* disabled */));
return owner;
}
String getDeviceOwnerPackageName() {
- return mDeviceOwnerPackageName;
+ return mDeviceOwner.packageName;
}
String getDeviceOwnerName() {
- return mDeviceOwnerName;
+ return mDeviceOwner.name;
}
void setDeviceOwner(String packageName, String ownerName) {
- mDeviceOwnerPackageName = packageName;
- mDeviceOwnerName = ownerName;
+ mDeviceOwner = new OwnerInfo(ownerName, packageName);
}
void setProfileOwner(String packageName, String ownerName, int userId) {
- mProfileOwners.put(userId, new String[] { packageName, ownerName });
+ mProfileOwners.put(userId, new OwnerInfo(ownerName, packageName, false /* disabled */));
}
void removeProfileOwner(int userId) {
@@ -131,17 +130,30 @@ public class DeviceOwner {
}
String getProfileOwnerPackageName(int userId) {
- String[] profileOwner = mProfileOwners.get(userId);
- return profileOwner != null ? profileOwner[0] : null;
+ OwnerInfo profileOwner = mProfileOwners.get(userId);
+ return profileOwner != null ? profileOwner.packageName : null;
}
String getProfileOwnerName(int userId) {
- String[] profileOwner = mProfileOwners.get(userId);
- return profileOwner != null ? profileOwner[1] : null;
+ OwnerInfo profileOwner = mProfileOwners.get(userId);
+ return profileOwner != null ? profileOwner.name : null;
+ }
+
+ boolean isProfileEnabled(int userId) {
+ OwnerInfo profileOwner = mProfileOwners.get(userId);
+ return profileOwner != null ? profileOwner.enabled : true;
+ }
+
+ void setProfileEnabled(int userId) {
+ OwnerInfo profileOwner = mProfileOwners.get(userId);
+ if (profileOwner == null) {
+ throw new IllegalArgumentException("No profile owner exists.");
+ }
+ profileOwner.enabled = true;
}
boolean hasDeviceOwner() {
- return mDeviceOwnerPackageName != null;
+ return mDeviceOwner != null;
}
static boolean isInstalled(String packageName, PackageManager pm) {
@@ -185,14 +197,18 @@ public class DeviceOwner {
String tag = parser.getName();
if (tag.equals(TAG_DEVICE_OWNER)) {
- mDeviceOwnerPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
- mDeviceOwnerName = parser.getAttributeValue(null, ATTR_NAME);
+ mDeviceOwner = new OwnerInfo(
+ parser.getAttributeValue(null, ATTR_NAME),
+ parser.getAttributeValue(null, ATTR_PACKAGE));
} else if (tag.equals(TAG_PROFILE_OWNER)) {
String profileOwnerPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
String profileOwnerName = parser.getAttributeValue(null, ATTR_NAME);
+ Boolean profileEnabled = Boolean.parseBoolean(
+ parser.getAttributeValue(null, ATTR_ENABLED));
int userId = Integer.parseInt(parser.getAttributeValue(null, ATTR_USERID));
mProfileOwners.put(userId,
- new String[] { profileOwnerPackageName, profileOwnerName });
+ new OwnerInfo(
+ profileOwnerPackageName, profileOwnerName, profileEnabled));
} else {
throw new XmlPullParserException(
"Unexpected tag in device owner file: " + tag);
@@ -220,21 +236,22 @@ public class DeviceOwner {
out.startDocument(null, true);
// Write device owner tag
- if (mDeviceOwnerPackageName != null) {
+ if (mDeviceOwner != null) {
out.startTag(null, TAG_DEVICE_OWNER);
- out.attribute(null, ATTR_PACKAGE, mDeviceOwnerPackageName);
- if (mDeviceOwnerName != null) {
- out.attribute(null, ATTR_NAME, mDeviceOwnerName);
+ out.attribute(null, ATTR_PACKAGE, mDeviceOwner.packageName);
+ if (mDeviceOwner.packageName != null) {
+ out.attribute(null, ATTR_NAME, mDeviceOwner.packageName);
}
out.endTag(null, TAG_DEVICE_OWNER);
}
// Write profile owner tags
if (mProfileOwners.size() > 0) {
- for (HashMap.Entry<Integer, String[]> owner : mProfileOwners.entrySet()) {
+ for (HashMap.Entry<Integer, OwnerInfo> owner : mProfileOwners.entrySet()) {
out.startTag(null, TAG_PROFILE_OWNER);
- out.attribute(null, ATTR_PACKAGE, owner.getValue()[0]);
- out.attribute(null, ATTR_NAME, owner.getValue()[1]);
+ out.attribute(null, ATTR_PACKAGE, owner.getValue().packageName);
+ out.attribute(null, ATTR_NAME, owner.getValue().name);
+ out.attribute(null, ATTR_ENABLED, String.valueOf(owner.getValue().enabled));
out.attribute(null, ATTR_USERID, Integer.toString(owner.getKey()));
out.endTag(null, TAG_PROFILE_OWNER);
}
@@ -271,4 +288,20 @@ public class DeviceOwner {
fileForWriting.finishWrite((FileOutputStream) stream);
}
}
+
+ static class OwnerInfo {
+ public String name;
+ public String packageName;
+ public boolean enabled = true; // only makes sense for managed profiles
+
+ public OwnerInfo(String name, String packageName, boolean enabled) {
+ this(name, packageName);
+ this.enabled = enabled;
+ }
+
+ public OwnerInfo(String name, String packageName) {
+ this.name = name;
+ this.packageName = packageName;
+ }
+ }
} \ No newline at end of file
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d6f9dea..cf45149 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2900,9 +2900,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
// Check if this is the profile owner who is calling
getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- Slog.d(LOG_TAG, "Enabling the profile for: " + UserHandle.getCallingUserId());
- long id = Binder.clearCallingIdentity();
+ int userId = UserHandle.getCallingUserId();
+ Slog.d(LOG_TAG, "Enabling the profile for: " + userId);
+
+ mDeviceOwner.setProfileEnabled(userId);
+ mDeviceOwner.writeOwnerFile();
+ long id = Binder.clearCallingIdentity();
try {
Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED);
intent.putExtra(Intent.EXTRA_USER, new UserHandle(UserHandle.getCallingUserId()));
@@ -2944,6 +2948,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return null;
}
+ @Override
+ public boolean isProfileEnabled(int userHandle) {
+ if (!mHasFeature) {
+ // If device policy management is not enabled, then the userHandle cannot belong to a
+ // managed profile. All other profiles are considered enabled.
+ return true;
+ }
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+
+ synchronized (this) {
+ if (mDeviceOwner != null) {
+ return mDeviceOwner.isProfileEnabled(userHandle);
+ }
+ }
+ return true;
+ }
+
private boolean isDeviceProvisioned() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) > 0;