Adds an enabled state in UserInfo instead of DevicePolicyManager

Bug: 14377459
Change-Id: Ib4ec43d87da96c3dddaf9b7ae1796f261863a182
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 68ab611..e437edb 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1778,7 +1778,7 @@
      * Sets the enabled state of the profile. A profile should be enabled only once it is ready to
      * be used. Only the profile owner can call this.
      *
-     * @see #isPRofileOwnerApp
+     * @see #isProfileOwnerApp
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
      */
@@ -1834,27 +1834,6 @@
 
     /**
      * @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 72b3c20..51ea7b1 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -109,7 +109,6 @@
     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/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index f53aa4c..c0383a3 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -27,8 +27,8 @@
  */
 public class UserInfo implements Parcelable {
 
-    /** 6 bits for user type */
-    public static final int FLAG_MASK_USER_TYPE = 0x0000003F;
+    /** 8 bits for user type */
+    public static final int FLAG_MASK_USER_TYPE = 0x000000FF;
 
     /**
      * *************************** NOTE ***************************
@@ -70,6 +70,11 @@
      */
     public static final int FLAG_MANAGED_PROFILE = 0x00000020;
 
+    /**
+     * Indicates that this user is disabled.
+     */
+    public static final int FLAG_DISABLED = 0x00000040;
+
 
     public static final int NO_PROFILE_GROUP_ID = -1;
 
@@ -117,6 +122,10 @@
         return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
     }
 
+    public boolean isEnabled() {
+        return (flags & FLAG_DISABLED) != FLAG_DISABLED;
+    }
+
     /**
      * @return true if this user can be switched to.
      **/
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index c3f7370..899a958 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -29,6 +29,7 @@
 interface IUserManager {
     UserInfo createUser(in String name, int flags);
     UserInfo createProfileForUser(in String name, int flags, int userHandle);
+    void setUserEnabled(int userHandle);
     boolean removeUser(int userHandle);
     void setUserName(int userHandle, String name);
     void setUserIcon(int userHandle, in Bitmap icon);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 1fe9337..b6a872a 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -437,6 +437,22 @@
     }
 
     /**
+     * Sets the user as enabled, if such an user exists.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * Note that the default is true, it's only that managed profiles might not be enabled.
+     *
+     * @param userHandle the id of the profile to enable
+     * @hide
+     */
+    public void setUserEnabled(int userHandle) {
+        try {
+            mService.setUserEnabled(userHandle);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Could not enable the profile", e);
+        }
+    }
+
+    /**
      * Return the number of users currently created on the device.
      */
     public int getUserCount() {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f8103de..14df347 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -23,7 +23,6 @@
 import android.app.ActivityManagerNative;
 import android.app.ActivityThread;
 import android.app.IStopUserCallback;
-import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -274,16 +273,6 @@
 
     /** Assume permissions already checked and caller's identity cleared */
     private List<UserInfo> getProfilesLocked(int userId, boolean enabledOnly) {
-        // 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++) {
@@ -291,23 +280,8 @@
             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 is 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));
-                }
+            if (enabledOnly && !profile.isEnabled()) {
+                continue;
             }
             users.add(profile);
         }
@@ -321,6 +295,18 @@
     }
 
     @Override
+    public void setUserEnabled(int userId) {
+        checkManageUsersPermission("enable user");
+        synchronized (mPackagesLock) {
+            UserInfo info = getUserInfoLocked(userId);
+            if (info != null && !info.isEnabled()) {
+                info.flags ^= UserInfo.FLAG_DISABLED;
+                writeUserLocked(info);
+            }
+        }
+    }
+
+    @Override
     public UserInfo getUserInfo(int userId) {
         checkManageUsersPermission("query user");
         synchronized (mPackagesLock) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index 3c46e40..1647425 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -53,7 +53,6 @@
     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;
 
@@ -104,8 +103,7 @@
      */
     static DeviceOwner createWithProfileOwner(String packageName, String ownerName, int userId) {
         DeviceOwner owner = new DeviceOwner();
-        owner.mProfileOwners.put(
-                userId, new OwnerInfo(ownerName, packageName, false /* disabled */));
+        owner.mProfileOwners.put(userId, new OwnerInfo(ownerName, packageName));
         return owner;
     }
 
@@ -122,7 +120,7 @@
     }
 
     void setProfileOwner(String packageName, String ownerName, int userId) {
-        mProfileOwners.put(userId, new OwnerInfo(ownerName, packageName, false /* disabled */));
+        mProfileOwners.put(userId, new OwnerInfo(ownerName, packageName));
     }
 
     void removeProfileOwner(int userId) {
@@ -139,19 +137,6 @@
         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 mDeviceOwner != null;
     }
@@ -203,12 +188,9 @@
                 } 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 OwnerInfo(
-                                    profileOwnerName, profileOwnerPackageName, profileEnabled));
+                            new OwnerInfo(profileOwnerName, profileOwnerPackageName));
                 } else {
                     throw new XmlPullParserException(
                             "Unexpected tag in device owner file: " + tag);
@@ -251,7 +233,6 @@
                     out.startTag(null, TAG_PROFILE_OWNER);
                     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);
                 }
@@ -292,12 +273,6 @@
     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;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index f1ee280..2025771 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -2903,11 +2903,10 @@
             int userId = UserHandle.getCallingUserId();
             Slog.d(LOG_TAG, "Enabling the profile for: " + userId);
 
-            mDeviceOwner.setProfileEnabled(userId);
-            mDeviceOwner.writeOwnerFile();
-
+            UserManager um = UserManager.get(mContext);
             long id = Binder.clearCallingIdentity();
             try {
+                um.setUserEnabled(userId);
                 Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED);
                 intent.putExtra(Intent.EXTRA_USER, new UserHandle(UserHandle.getCallingUserId()));
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
@@ -2948,23 +2947,6 @@
         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;