Merge "Pipe the user restriction to the admin dialog" into pi-dev
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index aeb4a85..8bab3ca 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -46,6 +46,7 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Utility class to host methods usable in adding a restricted padlock icon and showing admin
@@ -90,29 +91,29 @@
             // Restriction is not enforced.
             return null;
         } else if (enforcingUsers.size() > 1) {
-            return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+            return EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
         }
 
         final int restrictionSource = enforcingUsers.get(0).getUserRestrictionSource();
         final int adminUserId = enforcingUsers.get(0).getUserHandle().getIdentifier();
-
         if (restrictionSource == UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) {
             // Check if it is a profile owner of the user under consideration.
             if (adminUserId == userId) {
-                return getProfileOwner(context, adminUserId);
+                return getProfileOwner(context, userRestriction, adminUserId);
             } else {
                 // Check if it is a profile owner of a managed profile of the current user.
                 // Otherwise it is in a separate user and we return a default EnforcedAdmin.
                 final UserInfo parentUser = um.getProfileParent(adminUserId);
                 return (parentUser != null && parentUser.id == userId)
-                        ? getProfileOwner(context, adminUserId)
-                        : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                        ? getProfileOwner(context, userRestriction, adminUserId)
+                        : EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
             }
         } else if (restrictionSource == UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
             // When the restriction is enforced by device owner, return the device owner admin only
             // if the admin is for the {@param userId} otherwise return a default EnforcedAdmin.
             return adminUserId == userId
-                    ? getDeviceOwner(context) : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                    ? getDeviceOwner(context, userRestriction)
+                    : EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
         }
 
         // If the restriction is enforced by system then return null.
@@ -406,7 +407,6 @@
      * or {@code null} if no quality requirements are set. If the requirements are set by
      * multiple device admins, then the admin component will be set to {@code null} and userId to
      * {@link UserHandle#USER_NULL}.
-     *
      */
     public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context, int userId) {
         final LockSettingCheck check =
@@ -518,6 +518,11 @@
     }
 
     public static EnforcedAdmin getProfileOrDeviceOwner(Context context, int userId) {
+        return getProfileOrDeviceOwner(context, null, userId);
+    }
+
+    public static EnforcedAdmin getProfileOrDeviceOwner(
+            Context context, String enforcedRestriction, int userId) {
         if (userId == UserHandle.USER_NULL) {
             return null;
         }
@@ -528,18 +533,22 @@
         }
         ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
         }
         if (dpm.getDeviceOwnerUserId() == userId) {
             adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
             if (adminComponent != null) {
-                return new EnforcedAdmin(adminComponent, userId);
+                return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
             }
         }
         return null;
     }
 
     public static EnforcedAdmin getDeviceOwner(Context context) {
+        return getDeviceOwner(context, null);
+    }
+
+    private static EnforcedAdmin getDeviceOwner(Context context, String enforcedRestriction) {
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
         if (dpm == null) {
@@ -547,12 +556,18 @@
         }
         ComponentName adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, dpm.getDeviceOwnerUserId());
+            return new EnforcedAdmin(
+                    adminComponent, enforcedRestriction, dpm.getDeviceOwnerUserId());
         }
         return null;
     }
 
     private static EnforcedAdmin getProfileOwner(Context context, int userId) {
+        return getProfileOwner(context, null, userId);
+    }
+
+    private static EnforcedAdmin getProfileOwner(
+            Context context, String enforcedRestriction, int userId) {
         if (userId == UserHandle.USER_NULL) {
             return null;
         }
@@ -563,7 +578,7 @@
         }
         ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
         }
         return null;
     }
@@ -626,6 +641,7 @@
                 && isCurrentUserOrProfile(context, admin.userId)) {
             targetUserId = admin.userId;
         }
+        intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, admin.enforcedRestriction);
         context.startActivityAsUser(intent, new UserHandle(targetUserId));
     }
 
@@ -700,53 +716,71 @@
     }
 
     public static class EnforcedAdmin {
+        @Nullable
         public ComponentName component = null;
+        /**
+         * The restriction enforced by admin. It could be any user restriction or policy like
+         * {@link DevicePolicyManager#POLICY_DISABLE_CAMERA}.
+         */
+        @Nullable
+        public String enforcedRestriction = null;
         public int userId = UserHandle.USER_NULL;
 
         // We use this to represent the case where a policy is enforced by multiple admins.
         public final static EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin();
 
+        public static EnforcedAdmin createDefaultEnforcedAdminWithRestriction(
+                String enforcedRestriction) {
+            EnforcedAdmin enforcedAdmin = new EnforcedAdmin();
+            enforcedAdmin.enforcedRestriction = enforcedRestriction;
+            return enforcedAdmin;
+        }
+
         public EnforcedAdmin(ComponentName component, int userId) {
             this.component = component;
             this.userId = userId;
         }
 
+        public EnforcedAdmin(ComponentName component, String enforcedRestriction, int userId) {
+            this.component = component;
+            this.enforcedRestriction = enforcedRestriction;
+            this.userId = userId;
+        }
+
         public EnforcedAdmin(EnforcedAdmin other) {
             if (other == null) {
                 throw new IllegalArgumentException();
             }
             this.component = other.component;
+            this.enforcedRestriction = other.enforcedRestriction;
             this.userId = other.userId;
         }
 
-        public EnforcedAdmin() {}
+        public EnforcedAdmin() {
+        }
 
         @Override
-        public boolean equals(Object object) {
-            if (object == this) return true;
-            if (!(object instanceof EnforcedAdmin)) return false;
-            EnforcedAdmin other = (EnforcedAdmin) object;
-            if (userId != other.userId) {
-                return false;
-            }
-            if ((component == null && other.component == null) ||
-                    (component != null && component.equals(other.component))) {
-                return true;
-            }
-            return false;
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            EnforcedAdmin that = (EnforcedAdmin) o;
+            return userId == that.userId &&
+                    Objects.equals(component, that.component) &&
+                    Objects.equals(enforcedRestriction, that.enforcedRestriction);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(component, enforcedRestriction, userId);
         }
 
         @Override
         public String toString() {
-            return "EnforcedAdmin{component=" + component + ",userId=" + userId + "}";
-        }
-
-        public void copyTo(EnforcedAdmin other) {
-            if (other == null) {
-                throw new IllegalArgumentException();
-            }
-            other.component = component;
-            other.userId = userId;
+            return "EnforcedAdmin{" +
+                    "component=" + component +
+                    ", enforcedRestriction='" + enforcedRestriction +
+                    ", userId=" + userId +
+                    '}';
         }
     }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index 5f60868..710dbc22 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -32,6 +32,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.os.UserHandle;
 import android.os.UserManager;
 
 import org.junit.Before;
@@ -42,6 +43,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class RestrictedLockUtilsTest {
@@ -77,6 +79,42 @@
     }
 
     @Test
+    public void checkIfRestrictionEnforced_deviceOwner() {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId))).
+                thenReturn(Collections.singletonList(enforcingUser));
+        setUpDeviceOwner(mAdmin1);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @Test
+    public void checkIfRestrictionEnforced_profileOwner() {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId))).
+                thenReturn(Collections.singletonList(enforcingUser));
+        setUpProfileOwner(mAdmin1, mUserId);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @Test
     public void checkIfDevicePolicyServiceDisabled_noEnforceAdminForManagedProfile() {
         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
         final EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfAccountManagementDisabled(
@@ -263,4 +301,12 @@
         when(mDevicePolicyManager.getActiveAdminsAsUser(userId))
                 .thenReturn(Arrays.asList(activeAdmins));
     }
+
+    private void setUpDeviceOwner(ComponentName admin) {
+        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(admin);
+    }
+
+    private void setUpProfileOwner(ComponentName admin, int userId) {
+        when(mDevicePolicyManager.getProfileOwnerAsUser(userId)).thenReturn(admin);
+    }
 }