Merge "Fix work profile screen timeout policy" into nyc-dev
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index f15b8fe..96757bb 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2288,6 +2288,23 @@
     }
 
     /**
+     * Returns maximum time to lock that applied by all profiles in this user. We do this because we
+     * do not have a separate timeout to lock for work challenge only.
+     *
+     * @hide
+     */
+    public long getMaximumTimeToLockForUserAndProfiles(int userHandle) {
+        if (mService != null) {
+            try {
+                return mService.getMaximumTimeToLockForUserAndProfiles(userHandle);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return 0;
+    }
+
+    /**
      * Make the device lock immediately, as if the lock screen timeout has expired at the point of
      * this call.
      * <p>
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 1fb2283..6df1038 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -80,6 +80,7 @@
 
     void setMaximumTimeToLock(in ComponentName who, long timeMs, boolean parent);
     long getMaximumTimeToLock(in ComponentName who, int userHandle, boolean parent);
+    long getMaximumTimeToLockForUserAndProfiles(int userHandle);
 
     void lockNow(boolean parent);
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index e86ca82..59637be 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -459,58 +459,40 @@
         LockPatternUtils lockPatternUtils = new LockPatternUtils(context);
         EnforcedAdmin enforcedAdmin = null;
         final int userId = UserHandle.myUserId();
-        if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
-            // userId is managed profile and has a separate challenge, only consider
-            // the admins in that user.
-            final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId);
+        final UserManager um = UserManager.get(context);
+        final List<UserInfo> profiles = um.getProfiles(userId);
+        final int profilesSize = profiles.size();
+        // As we do not have a separate screen lock timeout settings for work challenge,
+        // we need to combine all profiles maximum time to lock even work challenge is
+        // enabled.
+        for (int i = 0; i < profilesSize; i++) {
+            final UserInfo userInfo = profiles.get(i);
+            final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id);
             if (admins == null) {
-                return null;
+                continue;
             }
             for (ComponentName admin : admins) {
-                if (dpm.getMaximumTimeToLock(admin, userId) > 0) {
+                if (dpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
                     if (enforcedAdmin == null) {
-                        enforcedAdmin = new EnforcedAdmin(admin, userId);
+                        enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
                     } else {
                         return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
                     }
-                }
-            }
-        } else {
-            // Return all admins for this user and the profiles that are visible from this
-            // user that do not use a separate work challenge.
-            final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
-            for (UserInfo userInfo : um.getProfiles(userId)) {
-                final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id);
-                if (admins == null) {
+                    // This same admins could have set policies both on the managed profile
+                    // and on the parent. So, if the admin has set the policy on the
+                    // managed profile here, we don't need to further check if that admin
+                    // has set policy on the parent admin.
                     continue;
                 }
-                final boolean isSeparateProfileChallengeEnabled =
-                        lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id);
-                for (ComponentName admin : admins) {
-                    if (!isSeparateProfileChallengeEnabled) {
-                        if (dpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
-                            if (enforcedAdmin == null) {
-                                enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
-                            } else {
-                                return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
-                            }
-                            // This same admins could have set policies both on the managed profile
-                            // and on the parent. So, if the admin has set the policy on the
-                            // managed profile here, we don't need to further check if that admin
-                            // has set policy on the parent admin.
-                            continue;
-                        }
-                    }
-                    if (userInfo.isManagedProfile()) {
-                        // If userInfo.id is a managed profile, we also need to look at
-                        // the policies set on the parent.
-                        DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo);
-                        if (parentDpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
-                            if (enforcedAdmin == null) {
-                                enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
-                            } else {
-                                return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
-                            }
+                if (userInfo.isManagedProfile()) {
+                    // If userInfo.id is a managed profile, we also need to look at
+                    // the policies set on the parent.
+                    final DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo);
+                    if (parentDpm.getMaximumTimeToLock(admin, userInfo.id) > 0) {
+                        if (enforcedAdmin == null) {
+                            enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+                        } else {
+                            return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
                         }
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e00bf6c..66754a7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -804,7 +804,7 @@
 
         // From DevicePolicyAdmin
         final long policyTimeout = mLockPatternUtils.getDevicePolicyManager()
-                .getMaximumTimeToLock(null, userId);
+                .getMaximumTimeToLockForUserAndProfiles(userId);
 
         long timeout;
 
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 858f7c7..9c2c6bf 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -375,7 +375,7 @@
                 } else {
                     mTrustAgentService.onConfigure(Collections.EMPTY_LIST, null);
                 }
-                final long maxTimeToLock = dpm.getMaximumTimeToLock(null);
+                final long maxTimeToLock = dpm.getMaximumTimeToLockForUserAndProfiles(mUserId);
                 if (maxTimeToLock != mMaximumTimeToLock) {
                     // If the timeout changes, cancel the alarm and send a timeout event to have
                     // the agent re-evaluate trust.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2b37112..fdea84b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -3978,6 +3978,15 @@
                         && timeMs > admin.maximumTimeToUnlock) {
                     timeMs = admin.maximumTimeToUnlock;
                 }
+                // If userInfo.id is a managed profile, we also need to look at
+                // the policies set on the parent.
+                if (admin.hasParentActiveAdmin()) {
+                    final ActiveAdmin parentAdmin = admin.getParentActiveAdmin();
+                    if (parentAdmin.maximumTimeToUnlock > 0
+                            && timeMs > parentAdmin.maximumTimeToUnlock) {
+                        timeMs = parentAdmin.maximumTimeToUnlock;
+                    }
+                }
             }
         }
 
@@ -4011,30 +4020,57 @@
         }
         enforceFullCrossUsersPermission(userHandle);
         synchronized (this) {
-            long time = 0;
-
             if (who != null) {
                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent);
-                return admin != null ? admin.maximumTimeToUnlock : time;
+                return admin != null ? admin.maximumTimeToUnlock : 0;
             }
-
             // Return the strictest policy across all participating admins.
             List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
                     userHandle, parent);
-            final int N = admins.size();
-            for (int i = 0; i < N; i++) {
-                ActiveAdmin admin = admins.get(i);
-                if (time == 0) {
-                    time = admin.maximumTimeToUnlock;
-                } else if (admin.maximumTimeToUnlock != 0
-                        && time > admin.maximumTimeToUnlock) {
-                    time = admin.maximumTimeToUnlock;
+            return getMaximumTimeToLockPolicyFromAdmins(admins);
+        }
+    }
+
+    @Override
+    public long getMaximumTimeToLockForUserAndProfiles(int userHandle) {
+        if (!mHasFeature) {
+            return 0;
+        }
+        enforceFullCrossUsersPermission(userHandle);
+        synchronized (this) {
+            // All admins for this user.
+            ArrayList<ActiveAdmin> admins = new ArrayList<ActiveAdmin>();
+            for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) {
+                DevicePolicyData policy = getUserData(userInfo.id);
+                admins.addAll(policy.mAdminList);
+                // If it is a managed profile, it may have parent active admins
+                if (userInfo.isManagedProfile()) {
+                    for (ActiveAdmin admin : policy.mAdminList) {
+                        if (admin.hasParentActiveAdmin()) {
+                            admins.add(admin.getParentActiveAdmin());
+                        }
+                    }
                 }
             }
-            return time;
+            return getMaximumTimeToLockPolicyFromAdmins(admins);
         }
     }
 
+    private long getMaximumTimeToLockPolicyFromAdmins(List<ActiveAdmin> admins) {
+        long time = 0;
+        final int N = admins.size();
+        for (int i = 0; i < N; i++) {
+            ActiveAdmin admin = admins.get(i);
+            if (time == 0) {
+                time = admin.maximumTimeToUnlock;
+            } else if (admin.maximumTimeToUnlock != 0
+                    && time > admin.maximumTimeToUnlock) {
+                time = admin.maximumTimeToUnlock;
+            }
+        }
+        return time;
+    }
+
     @Override
     public void lockNow(boolean parent) {
         if (!mHasFeature) {