Merge "Make ConfirmCredentials take user into account when creating intent"
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 23e4d97..3910657 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -21,11 +21,14 @@
 import android.app.trust.ITrustManager;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.UserInfo;
 import android.os.Binder;
 import android.os.RemoteException;
 import android.os.IBinder;
+import android.os.IUserManager;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.view.IWindowManager;
 import android.view.IOnKeyguardExitResult;
 import android.view.WindowManagerGlobal;
@@ -40,6 +43,7 @@
 public class KeyguardManager {
     private IWindowManager mWM;
     private ITrustManager mTrustManager;
+    private IUserManager mUserManager;
 
     /**
      * Intent used to prompt user for device credentials.
@@ -49,6 +53,13 @@
             "android.app.action.CONFIRM_DEVICE_CREDENTIAL";
 
     /**
+     * Intent used to prompt user for device credentials.
+     * @hide
+     */
+    public static final String ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER =
+            "android.app.action.CONFIRM_DEVICE_CREDENTIAL_WITH_USER";
+
+    /**
      * A CharSequence dialog title to show to the user when used with a
      * {@link #ACTION_CONFIRM_DEVICE_CREDENTIAL}.
      * @hide
@@ -71,7 +82,7 @@
      * @return the intent for launching the activity or null if no password is required.
      **/
     public Intent createConfirmDeviceCredentialIntent(CharSequence title, CharSequence description) {
-        if (!isKeyguardSecure()) return null;
+        if (!isDeviceSecure()) return null;
         Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL);
         intent.putExtra(EXTRA_TITLE, title);
         intent.putExtra(EXTRA_DESCRIPTION, description);
@@ -81,6 +92,28 @@
     }
 
     /**
+     * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
+     * for the given user. The caller is expected to launch this activity using
+     * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
+     * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
+     *
+     * @return the intent for launching the activity or null if no password is required.
+     *
+     * @hide
+     */
+    public Intent createConfirmDeviceCredentialIntent(
+            CharSequence title, CharSequence description, int userId) {
+        if (!isDeviceSecure(userId)) return null;
+        Intent intent = new Intent(ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
+        intent.putExtra(EXTRA_TITLE, title);
+        intent.putExtra(EXTRA_DESCRIPTION, description);
+        intent.putExtra(Intent.EXTRA_USER_ID, userId);
+        // For security reasons, only allow this to come from system settings.
+        intent.setPackage("com.android.settings");
+        return intent;
+    }
+
+    /**
      * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD}
      * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED}
      * instead; this allows you to seamlessly hide the keyguard as your application
@@ -162,6 +195,8 @@
         mWM = WindowManagerGlobal.getWindowManagerService();
         mTrustManager = ITrustManager.Stub.asInterface(
                 ServiceManager.getService(Context.TRUST_SERVICE));
+        mUserManager = IUserManager.Stub.asInterface(
+                ServiceManager.getService(Context.USER_SERVICE));
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6c00e73..50575e8 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1624,21 +1624,23 @@
                     PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
                             | PendingIntent.FLAG_IMMUTABLE, null);
             int flags = intent.getFlags();
-            intent = km.createConfirmDeviceCredentialIntent(null, null);
-            intent.addFlags(FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
-            intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
-            intent.putExtra(Intent.EXTRA_USER_ID, userId);
-            intent.setFlags(flags);
+            Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, user.id);
+            if (newIntent != null) {
+                intent = newIntent;
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+                intent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
+                intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
+                intent.setFlags(flags);
 
-            resolvedType = null;
-            callingUid = realCallingUid;
-            callingPid = realCallingPid;
+                resolvedType = null;
+                callingUid = realCallingUid;
+                callingPid = realCallingPid;
 
-            UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId);
-            aInfo = resolveActivity(intent, null, PackageManager.MATCH_DEFAULT_ONLY
-                    | ActivityManagerService.STOCK_PM_FLAGS, null, parent.id);
+                UserInfo parent = UserManager.get(mService.mContext).getProfileParent(userId);
+                aInfo = resolveActivity(intent, null, PackageManager.MATCH_DEFAULT_ONLY
+                        | ActivityManagerService.STOCK_PM_FLAGS, null, parent.id);
+            }
         }
 
         if (abort) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 4b6db99..d888c56 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -53,7 +53,6 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.trust.TrustAgentService;
 import android.util.ArraySet;
@@ -681,7 +680,9 @@
         public boolean isDeviceSecure(int userId) throws RemoteException {
             userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
                     false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
-            userId = resolveProfileParent(userId);
+            if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
+                userId = resolveProfileParent(userId);
+            }
 
             long token = Binder.clearCallingIdentity();
             try {