Create Work Challenge per-user condition

Change the current static condition to a per-user condition so we
can check and enable/disable the work challenge properly. Also add
an isAllowed API, as the Work Challenge can only be used when the
user's DPC targets N or above to maintain backwards compatibility.

Change-Id: I0cb8b475838816801868ffb24726407aa257b4de
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 1a21f5c..377d52f 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -695,7 +695,7 @@
             unlockUser(userId, token);
 
             UserInfo info = UserManager.get(mContext).getUserInfo(userId);
-            if (LockPatternUtils.isSeparateWorkChallengeEnabled() && info.isManagedProfile()) {
+            if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
                 TrustManager trustManager =
                         (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
                 trustManager.setDeviceLockedForUser(userId, false);
diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java
index 137fa27..816c791 100644
--- a/services/core/java/com/android/server/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/LockSettingsStorage.java
@@ -71,6 +71,7 @@
     private final Object mFileWriteLock = new Object();
 
     private int mStoredCredentialType;
+    private LockPatternUtils mLockPatternUtils;
 
     class CredentialHash {
         static final int TYPE_NONE = -1;
@@ -100,6 +101,7 @@
     public LockSettingsStorage(Context context, Callback callback) {
         mContext = context;
         mOpenHelper = new DatabaseHelper(context, callback);
+        mLockPatternUtils = new LockPatternUtils(context);
     }
 
     public void writeKeyValue(String key, String value, int userId) {
@@ -388,7 +390,7 @@
 
     private int getUserParentOrSelfId(int userId) {
         // Device supports per user encryption, so lock is applied to the given user.
-        if (LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
             return userId;
         }
         // Device uses Block Based Encryption, and the parent user's lock is used for the whole
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 7172859..56757ca 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -143,6 +143,8 @@
 
     private volatile UserManagerService mUserManager;
 
+    private final LockPatternUtils mLockPatternUtils;
+
     UserController(ActivityManagerService service) {
         mService = service;
         mHandler = mService.mHandler;
@@ -150,6 +152,7 @@
         final UserState uss = new UserState(UserHandle.SYSTEM);
         mStartedUsers.put(UserHandle.USER_SYSTEM, uss);
         mUserLru.add(UserHandle.USER_SYSTEM);
+        mLockPatternUtils = new LockPatternUtils(mService.mContext);
         updateStartedUserArrayLocked();
     }
 
@@ -1294,13 +1297,12 @@
      * intercept activity launches for work apps when the Work Challenge is present.
      */
     boolean shouldConfirmCredentials(int userId) {
-        final UserInfo user = getUserInfo(userId);
-        if (!user.isManagedProfile() || !LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
             return false;
         }
         final KeyguardManager km = (KeyguardManager) mService.mContext
                 .getSystemService(KEYGUARD_SERVICE);
-        return km.isDeviceLocked(user.id);
+        return km.isDeviceLocked(userId);
     }
 
     void dump(PrintWriter pw, boolean dumpAll) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 3d614a3..ce6b369 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -276,6 +276,8 @@
     private final ArrayList<UserRestrictionsListener> mUserRestrictionsListeners =
             new ArrayList<>();
 
+    private final LockPatternUtils mLockPatternUtils;
+
     private static UserManagerService sInstance;
 
     public static UserManagerService getInstance() {
@@ -320,6 +322,7 @@
         }
         mLocalService = new LocalService();
         LocalServices.addService(UserManagerInternal.class, mLocalService);
+        mLockPatternUtils = new LockPatternUtils(mContext);
     }
 
     void systemReady() {
@@ -456,7 +459,7 @@
     @Override
     public int getCredentialOwnerProfile(int userHandle) {
         checkManageUsersPermission("get the credential owner");
-        if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+        if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) {
             synchronized (mUsersLock) {
                 UserInfo profileParent = getProfileParentLU(userHandle);
                 if (profileParent != null) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index d888c56..78e3f7f 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -290,14 +290,9 @@
     }
 
     public void setDeviceLockedForUser(int userId, boolean locked) {
-        if (LockPatternUtils.isSeparateWorkChallengeEnabled()) {
-            UserInfo info = mUserManager.getUserInfo(userId);
-            if (info.isManagedProfile()) {
-                synchronized (mDeviceLockedForUser) {
-                    mDeviceLockedForUser.put(userId, locked);
-                }
-            } else {
-                Log.wtf(TAG, "Requested to change lock state for non-profile user " + userId);
+        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+            synchronized (mDeviceLockedForUser) {
+                mDeviceLockedForUser.put(userId, locked);
             }
         }
     }
@@ -669,7 +664,7 @@
         public boolean isDeviceLocked(int userId) throws RemoteException {
             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                     false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
-            if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+            if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
                 userId = resolveProfileParent(userId);
             }
 
@@ -680,13 +675,13 @@
         public boolean isDeviceSecure(int userId) throws RemoteException {
             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                     false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
-            if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+            if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
                 userId = resolveProfileParent(userId);
             }
 
             long token = Binder.clearCallingIdentity();
             try {
-                return new LockPatternUtils(mContext).isSecure(userId);
+                return mLockPatternUtils.isSecure(userId);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }