[DO NOT MERGE] Do not clear calling identify when using BiometricPrompt from FingerprintService.

Bug: 214261879
Test: atest AuthControllerTest
Test: Manually verify with test apps in bug
Change-Id: I8ae9f2b8a970bf7e5d32121dc358f7d0f0d060b8
(cherry picked from commit 2d60fb3647a838c4c7f10c6f98bf98be4508b119)
Merged-In: I8ae9f2b8a970bf7e5d32121dc358f7d0f0d060b8
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 6b5bec9..520234b 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -421,6 +421,18 @@
         }
 
         /**
+         * Set if BiometricPrompt is being used by the legacy fingerprint manager API.
+         * @param sensorId sensor id
+         * @return This builder.
+         * @hide
+         */
+        @NonNull
+        public Builder setIsForLegacyFingerprintManager(int sensorId) {
+            mPromptInfo.setIsForLegacyFingerprintManager(sensorId);
+            return this;
+        }
+
+        /**
          * Creates a {@link BiometricPrompt}.
          *
          * @return An instance of {@link BiometricPrompt}.
@@ -861,28 +873,36 @@
             @NonNull @CallbackExecutor Executor executor,
             @NonNull AuthenticationCallback callback,
             int userId) {
-        authenticateUserForOperation(cancel, executor, callback, userId, 0 /* operationId */);
+        if (cancel == null) {
+            throw new IllegalArgumentException("Must supply a cancellation signal");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must supply an executor");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("Must supply a callback");
+        }
+
+        authenticateInternal(0 /* operationId */, cancel, executor, callback, userId);
     }
 
     /**
-     * Authenticates for the given user and keystore operation.
+     * Authenticates for the given keystore operation.
      *
      * @param cancel An object that can be used to cancel authentication
      * @param executor An executor to handle callback events
      * @param callback An object to receive authentication events
-     * @param userId The user to authenticate
      * @param operationId The keystore operation associated with authentication
      *
      * @return A requestId that can be used to cancel this operation.
      *
      * @hide
      */
-    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
-    public long authenticateUserForOperation(
+    @RequiresPermission(USE_BIOMETRIC)
+    public long authenticateForOperation(
             @NonNull CancellationSignal cancel,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull AuthenticationCallback callback,
-            int userId,
             long operationId) {
         if (cancel == null) {
             throw new IllegalArgumentException("Must supply a cancellation signal");
@@ -894,7 +914,7 @@
             throw new IllegalArgumentException("Must supply a callback");
         }
 
-        return authenticateInternal(operationId, cancel, executor, callback, userId);
+        return authenticateInternal(operationId, cancel, executor, callback, mContext.getUserId());
     }
 
     /**
@@ -1028,7 +1048,7 @@
     private void cancelAuthentication(long requestId) {
         if (mService != null) {
             try {
-                mService.cancelAuthentication(mToken, mContext.getOpPackageName(), requestId);
+                mService.cancelAuthentication(mToken, mContext.getPackageName(), requestId);
             } catch (RemoteException e) {
                 Log.e(TAG, "Unable to cancel authentication", e);
             }
@@ -1087,7 +1107,7 @@
             }
 
             final long authId = mService.authenticate(mToken, operationId, userId,
-                    mBiometricServiceReceiver, mContext.getOpPackageName(), promptInfo);
+                    mBiometricServiceReceiver, mContext.getPackageName(), promptInfo);
             cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
             return authId;
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
index 3d9517f..b336a9f 100644
--- a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
+++ b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl
@@ -19,7 +19,7 @@
  * ITestSession callback for FingerprintManager and BiometricManager.
  * @hide
  */
-interface ITestSessionCallback {
+oneway interface ITestSessionCallback {
     void onCleanupStarted(int userId);
     void onCleanupFinished(int userId);
 }
diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java
index e6b762a..2742f0e 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -46,6 +46,7 @@
     @NonNull private List<Integer> mAllowedSensorIds = new ArrayList<>();
     private boolean mAllowBackgroundAuthentication;
     private boolean mIgnoreEnrollmentState;
+    private boolean mIsForLegacyFingerprintManager = false;
 
     public PromptInfo() {
 
@@ -68,6 +69,7 @@
         mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader());
         mAllowBackgroundAuthentication = in.readBoolean();
         mIgnoreEnrollmentState = in.readBoolean();
+        mIsForLegacyFingerprintManager = in.readBoolean();
     }
 
     public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() {
@@ -105,10 +107,15 @@
         dest.writeList(mAllowedSensorIds);
         dest.writeBoolean(mAllowBackgroundAuthentication);
         dest.writeBoolean(mIgnoreEnrollmentState);
+        dest.writeBoolean(mIsForLegacyFingerprintManager);
     }
 
     public boolean containsTestConfigurations() {
-        if (!mAllowedSensorIds.isEmpty()) {
+        if (mIsForLegacyFingerprintManager
+                && mAllowedSensorIds.size() == 1
+                && !mAllowBackgroundAuthentication) {
+            return false;
+        } else if (!mAllowedSensorIds.isEmpty()) {
             return true;
         } else if (mAllowBackgroundAuthentication) {
             return true;
@@ -188,7 +195,8 @@
     }
 
     public void setAllowedSensorIds(@NonNull List<Integer> sensorIds) {
-        mAllowedSensorIds = sensorIds;
+        mAllowedSensorIds.clear();
+        mAllowedSensorIds.addAll(sensorIds);
     }
 
     public void setAllowBackgroundAuthentication(boolean allow) {
@@ -199,6 +207,12 @@
         mIgnoreEnrollmentState = ignoreEnrollmentState;
     }
 
+    public void setIsForLegacyFingerprintManager(int sensorId) {
+        mIsForLegacyFingerprintManager = true;
+        mAllowedSensorIds.clear();
+        mAllowedSensorIds.add(sensorId);
+    }
+
     // Getters
 
     public CharSequence getTitle() {
@@ -272,4 +286,8 @@
     public boolean isIgnoreEnrollmentState() {
         return mIgnoreEnrollmentState;
     }
+
+    public boolean isForLegacyFingerprintManager() {
+        return mIsForLegacyFingerprintManager;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index df20b83..7ab214e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -134,7 +134,7 @@
     private class BiometricTaskStackListener extends TaskStackListener {
         @Override
         public void onTaskStackChanged() {
-            mHandler.post(AuthController.this::handleTaskStackChanged);
+            mHandler.post(AuthController.this::cancelIfOwnerIsNotInForeground);
         }
     }
 
@@ -181,7 +181,7 @@
         }
     };
 
-    private void handleTaskStackChanged() {
+    private void cancelIfOwnerIsNotInForeground() {
         mExecution.assertIsMainThread();
         if (mCurrentDialog != null) {
             try {
@@ -193,7 +193,7 @@
                     final String topPackage = runningTasks.get(0).topActivity.getPackageName();
                     if (!topPackage.contentEquals(clientPackage)
                             && !Utils.isSystem(mContext, clientPackage)) {
-                        Log.w(TAG, "Evicting client due to: " + topPackage);
+                        Log.e(TAG, "Evicting client due to: " + topPackage);
                         mCurrentDialog.dismissWithoutCallback(true /* animate */);
                         mCurrentDialog = null;
                         mOrientationListener.disable();
@@ -814,6 +814,10 @@
         mCurrentDialog = newDialog;
         mCurrentDialog.show(mWindowManager, savedState);
         mOrientationListener.enable();
+
+        if (!promptInfo.isAllowBackgroundAuthentication()) {
+            mHandler.post(this::cancelIfOwnerIsNotInForeground);
+        }
     }
 
     private void onDialogDismissed(@DismissedReason int reason) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 08c7714..2b7c984 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -555,15 +555,25 @@
     }
 
     @Test
+    public void testClientNotified_whenTaskStackChangesDuringShow() throws Exception {
+        switchTask("other_package");
+        showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
+
+        mTestableLooper.processAllMessages();
+
+        assertNull(mAuthController.mCurrentDialog);
+        assertNull(mAuthController.mReceiver);
+        verify(mDialog1).dismissWithoutCallback(true /* animate */);
+        verify(mReceiver).onDialogDismissed(
+                eq(BiometricPrompt.DISMISSED_REASON_USER_CANCEL),
+                eq(null) /* credentialAttestation */);
+    }
+
+    @Test
     public void testClientNotified_whenTaskStackChangesDuringAuthentication() throws Exception {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
 
-        List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>();
-        ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class);
-        taskInfo.topActivity = mock(ComponentName.class);
-        when(taskInfo.topActivity.getPackageName()).thenReturn("other_package");
-        tasks.add(taskInfo);
-        when(mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks);
+        switchTask("other_package");
 
         mAuthController.mTaskStackListener.onTaskStackChanged();
         mTestableLooper.processAllMessages();
@@ -640,6 +650,16 @@
                 BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT);
     }
 
+    private void switchTask(String packageName) {
+        final List<ActivityManager.RunningTaskInfo> tasks = new ArrayList<>();
+        final ActivityManager.RunningTaskInfo taskInfo =
+                mock(ActivityManager.RunningTaskInfo.class);
+        taskInfo.topActivity = mock(ComponentName.class);
+        when(taskInfo.topActivity.getPackageName()).thenReturn(packageName);
+        tasks.add(taskInfo);
+        when(mActivityTaskManager.getTasks(anyInt())).thenReturn(tasks);
+    }
+
     private PromptInfo createTestPromptInfo() {
         PromptInfo promptInfo = new PromptInfo();
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 358263d..92c8c9b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -118,7 +118,7 @@
         mIsStrongBiometric = isStrongBiometric;
         mOperationId = operationId;
         mRequireConfirmation = requireConfirmation;
-        mActivityTaskManager = ActivityTaskManager.getInstance();
+        mActivityTaskManager = getActivityTaskManager();
         mBiometricManager = context.getSystemService(BiometricManager.class);
         mTaskStackListener = taskStackListener;
         mLockoutTracker = lockoutTracker;
@@ -146,6 +146,10 @@
         return mStartTimeMs;
     }
 
+    protected ActivityTaskManager getActivityTaskManager() {
+        return ActivityTaskManager.getInstance();
+    }
+
     @Override
     public void binderDied() {
         final boolean clearListener = !isBiometricPrompt();
@@ -322,45 +326,50 @@
                     sendCancelOnly(listener);
                 }
             });
-        } else {
-            // Allow system-defined limit of number of attempts before giving up
-            final @LockoutTracker.LockoutMode int lockoutMode =
-                    handleFailedAttempt(getTargetUserId());
-            if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
-                markAlreadyDone();
+        } else { // not authenticated
+            if (isBackgroundAuth) {
+                Slog.e(TAG, "cancelling due to background auth");
+                cancel();
+            } else {
+                // Allow system-defined limit of number of attempts before giving up
+                final @LockoutTracker.LockoutMode int lockoutMode =
+                        handleFailedAttempt(getTargetUserId());
+                if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
+                    markAlreadyDone();
+                }
+
+                final CoexCoordinator coordinator = CoexCoordinator.getInstance();
+                coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode,
+                        new CoexCoordinator.Callback() {
+                            @Override
+                            public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
+                                if (listener != null) {
+                                    try {
+                                        listener.onAuthenticationFailed(getSensorId());
+                                    } catch (RemoteException e) {
+                                        Slog.e(TAG, "Unable to notify listener", e);
+                                    }
+                                }
+                            }
+
+                            @Override
+                            public void sendHapticFeedback() {
+                                if (listener != null && mShouldVibrate) {
+                                    vibrateError();
+                                }
+                            }
+
+                            @Override
+                            public void handleLifecycleAfterAuth() {
+                                AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */);
+                            }
+
+                            @Override
+                            public void sendAuthenticationCanceled() {
+                                sendCancelOnly(listener);
+                            }
+                        });
             }
-
-            final CoexCoordinator coordinator = CoexCoordinator.getInstance();
-            coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode,
-                    new CoexCoordinator.Callback() {
-                @Override
-                public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
-                    if (listener != null) {
-                        try {
-                            listener.onAuthenticationFailed(getSensorId());
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Unable to notify listener", e);
-                        }
-                    }
-                }
-
-                @Override
-                public void sendHapticFeedback() {
-                    if (listener != null && mShouldVibrate) {
-                        vibrateError();
-                    }
-                }
-
-                @Override
-                public void handleLifecycleAfterAuth() {
-                    AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */);
-                }
-
-                @Override
-                public void sendAuthenticationCanceled() {
-                    sendCancelOnly(listener);
-                }
-            });
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index b44f4dc..3a93d82 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -331,12 +331,12 @@
                     provider.second.getSensorProperties(sensorId);
             if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)
                     && sensorProps != null && sensorProps.isAnyUdfpsType()) {
-                identity = Binder.clearCallingIdentity();
                 try {
                     return authenticateWithPrompt(operationId, sensorProps, userId, receiver,
-                            ignoreEnrollmentState);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
+                            opPackageName, ignoreEnrollmentState);
+                } catch (PackageManager.NameNotFoundException e) {
+                    Slog.e(TAG, "Invalid package", e);
+                    return -1;
                 }
             }
             return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
@@ -349,12 +349,15 @@
                 @NonNull final FingerprintSensorPropertiesInternal props,
                 final int userId,
                 final IFingerprintServiceReceiver receiver,
-                boolean ignoreEnrollmentState) {
+                final String opPackageName,
+                boolean ignoreEnrollmentState) throws PackageManager.NameNotFoundException {
 
             final Context context = getUiContext();
+            final Context promptContext = context.createPackageContextAsUser(
+                    opPackageName, 0 /* flags */, UserHandle.getUserHandleForUid(userId));
             final Executor executor = context.getMainExecutor();
 
-            final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(context)
+            final BiometricPrompt biometricPrompt = new BiometricPrompt.Builder(promptContext)
                     .setTitle(context.getString(R.string.biometric_dialog_default_title))
                     .setSubtitle(context.getString(R.string.fingerprint_dialog_default_subtitle))
                     .setNegativeButton(
@@ -368,8 +371,7 @@
                                     Slog.e(TAG, "Remote exception in negative button onClick()", e);
                                 }
                             })
-                    .setAllowedSensorIds(new ArrayList<>(
-                            Collections.singletonList(props.sensorId)))
+                    .setIsForLegacyFingerprintManager(props.sensorId)
                     .setIgnoreEnrollmentState(ignoreEnrollmentState)
                     .build();
 
@@ -423,8 +425,8 @@
                         }
                     };
 
-            return biometricPrompt.authenticateUserForOperation(
-                    new CancellationSignal(), executor, promptCallback, userId, operationId);
+            return biometricPrompt.authenticateForOperation(
+                    new CancellationSignal(), executor, promptCallback, operationId);
         }
 
         @Override