diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index aa4b0514c02d8..64877aa69c4d5 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -27,6 +27,12 @@ import android.os.ParcelFileDescriptor; * {@hide} */ interface IUserManager { + + /* + * DO NOT MOVE - UserManager.h depends on the ordering of this function. + */ + int getCredentialOwnerProfile(int userHandle); + UserInfo createUser(in String name, int flags); UserInfo createProfileForUser(in String name, int flags, int userHandle); void setUserEnabled(int userHandle); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 83a1993775de0..045c1e88ec010 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1067,6 +1067,22 @@ public class UserManager { return profiles; } + /** + * Returns the device credential owner id of the profile from + * which this method is called, or userHandle if called from a user that + * is not a profile. + * + * @hide + */ + public int getCredentialOwnerProfile(int userHandle) { + try { + return mService.getCredentialOwnerProfile(userHandle); + } catch (RemoteException re) { + Log.w(TAG, "Could not get credential owner", re); + return -1; + } + } + /** * Returns the parent of the profile which this method is called from * or null if called from a user that is not a profile. diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 19c5f0fdc0fcc..6edf5f4495a0d 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -135,6 +135,11 @@ public class UserManagerService extends IUserManager.Stub { // without first making sure that the rest of the framework is prepared for it. private static final int MAX_MANAGED_PROFILES = 1; + /** + * Flag indicating whether device credentials are shared among same-user profiles. + */ + private static final boolean CONFIG_PROFILES_SHARE_CREDENTIAL = true; + // Set of user restrictions, which can only be enforced by the system private static final Set SYSTEM_CONTROLLED_RESTRICTIONS = Sets.newArraySet( UserManager.DISALLOW_RECORD_AUDIO); @@ -316,6 +321,21 @@ public class UserManagerService extends IUserManager.Stub { return users; } + @Override + public int getCredentialOwnerProfile(int userHandle) { + checkManageUsersPermission("get the credential owner"); + if (CONFIG_PROFILES_SHARE_CREDENTIAL) { + synchronized (mPackagesLock) { + UserInfo profileParent = getProfileParentLocked(userHandle); + if (profileParent != null) { + return profileParent.id; + } + } + } + + return userHandle; + } + @Override public UserInfo getProfileParent(int userHandle) { checkManageUsersPermission("get the profile parent"); @@ -943,7 +963,7 @@ public class UserManagerService extends IUserManager.Stub { } } - private void writeRestrictionsLocked(XmlSerializer serializer, Bundle restrictions) + private void writeRestrictionsLocked(XmlSerializer serializer, Bundle restrictions) throws IOException { serializer.startTag(null, TAG_RESTRICTIONS); writeBoolean(serializer, restrictions, UserManager.DISALLOW_CONFIG_WIFI);