diff options
5 files changed, 99 insertions, 21 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java index 2e40f6096ccb..71d1015cd6e3 100644 --- a/core/java/android/hardware/biometrics/BiometricPrompt.java +++ b/core/java/android/hardware/biometrics/BiometricPrompt.java @@ -460,6 +460,20 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan } /** + * Set the class name of ConfirmDeviceCredentialActivity. + * + * @return This builder. + * @hide + */ + @NonNull + @RequiresPermission(anyOf = {TEST_BIOMETRIC, USE_BIOMETRIC_INTERNAL}) + public Builder setClassNameIfItIsConfirmDeviceCredentialActivity() { + mPromptInfo.setClassNameIfItIsConfirmDeviceCredentialActivity( + mContext.getClass().getName()); + return this; + } + + /** * Creates a {@link BiometricPrompt}. * * @return An instance of {@link BiometricPrompt}. diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java index 02aad1dc4b4b..f1fce7290f99 100644 --- a/core/java/android/hardware/biometrics/PromptInfo.java +++ b/core/java/android/hardware/biometrics/PromptInfo.java @@ -48,6 +48,7 @@ public class PromptInfo implements Parcelable { private boolean mAllowBackgroundAuthentication; private boolean mIgnoreEnrollmentState; private boolean mIsForLegacyFingerprintManager = false; + private String mClassNameIfItIsConfirmDeviceCredentialActivity = null; public PromptInfo() { @@ -72,6 +73,7 @@ public class PromptInfo implements Parcelable { mAllowBackgroundAuthentication = in.readBoolean(); mIgnoreEnrollmentState = in.readBoolean(); mIsForLegacyFingerprintManager = in.readBoolean(); + mClassNameIfItIsConfirmDeviceCredentialActivity = in.readString(); } public static final Creator<PromptInfo> CREATOR = new Creator<PromptInfo>() { @@ -111,6 +113,7 @@ public class PromptInfo implements Parcelable { dest.writeBoolean(mAllowBackgroundAuthentication); dest.writeBoolean(mIgnoreEnrollmentState); dest.writeBoolean(mIsForLegacyFingerprintManager); + dest.writeString(mClassNameIfItIsConfirmDeviceCredentialActivity); } public boolean containsTestConfigurations() { @@ -122,6 +125,8 @@ public class PromptInfo implements Parcelable { return true; } else if (mAllowBackgroundAuthentication) { return true; + } else if (mClassNameIfItIsConfirmDeviceCredentialActivity != null) { + return true; } return false; } @@ -222,6 +227,13 @@ public class PromptInfo implements Parcelable { mAllowedSensorIds.add(sensorId); } + /** + * Set the class name of ConfirmDeviceCredentialActivity. + */ + void setClassNameIfItIsConfirmDeviceCredentialActivity(String className) { + mClassNameIfItIsConfirmDeviceCredentialActivity = className; + } + // Getters public CharSequence getTitle() { @@ -303,4 +315,12 @@ public class PromptInfo implements Parcelable { public boolean isForLegacyFingerprintManager() { return mIsForLegacyFingerprintManager; } + + /** + * Get the class name of ConfirmDeviceCredentialActivity. Returns null if the direct caller is + * not ConfirmDeviceCredentialActivity. + */ + public String getClassNameIfItIsConfirmDeviceCredentialActivity() { + return mClassNameIfItIsConfirmDeviceCredentialActivity; + } } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java index 76181094c4b3..4acf659c6b81 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java @@ -819,6 +819,11 @@ public class AuthContainerView extends LinearLayout } @Override + public String getClassNameIfItIsConfirmDeviceCredentialActivity() { + return mConfig.mPromptInfo.getClassNameIfItIsConfirmDeviceCredentialActivity(); + } + + @Override public void animateToCredentialUI(boolean isError) { if (mBiometricView != null) { mBiometricView.startTransitionToCredentialUI(isError); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java index 2ca4f0cfe3b1..398268b8e276 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java @@ -26,6 +26,7 @@ import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.TaskStackListener; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -231,28 +232,21 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, mExecution.assertIsMainThread(); if (mCurrentDialog != null) { try { - final String clientPackage = mCurrentDialog.getOpPackageName(); - Log.w(TAG, "Task stack changed, current client: " + clientPackage); - final List<ActivityManager.RunningTaskInfo> runningTasks = - mActivityTaskManager.getTasks(1); - if (!runningTasks.isEmpty()) { - final String topPackage = runningTasks.get(0).topActivity.getPackageName(); - if (!topPackage.contentEquals(clientPackage) - && !Utils.isSystem(mContext, clientPackage)) { - Log.e(TAG, "Evicting client due to: " + topPackage); - mCurrentDialog.dismissWithoutCallback(true /* animate */); - mCurrentDialog = null; - - for (Callback cb : mCallbacks) { - cb.onBiometricPromptDismissed(); - } + if (isOwnerInBackground()) { + Log.w(TAG, "Evicting client due to top activity is not : " + + mCurrentDialog.getOpPackageName()); + mCurrentDialog.dismissWithoutCallback(true /* animate */); + mCurrentDialog = null; + + for (Callback cb : mCallbacks) { + cb.onBiometricPromptDismissed(); + } - if (mReceiver != null) { - mReceiver.onDialogDismissed( - BiometricPrompt.DISMISSED_REASON_USER_CANCEL, - null /* credentialAttestation */); - mReceiver = null; - } + if (mReceiver != null) { + mReceiver.onDialogDismissed( + BiometricPrompt.DISMISSED_REASON_USER_CANCEL, + null /* credentialAttestation */); + mReceiver = null; } } } catch (RemoteException e) { @@ -261,6 +255,45 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks, } } + private boolean isOwnerInBackground() { + if (mCurrentDialog != null) { + final String clientPackage = mCurrentDialog.getOpPackageName(); + + final List<ActivityManager.RunningTaskInfo> runningTasks = + mActivityTaskManager.getTasks(1); + if (runningTasks == null || runningTasks.isEmpty()) { + Log.w(TAG, "No running tasks reported"); + return false; + } + + final boolean isSystemApp = Utils.isSystem(mContext, clientPackage); + + final ComponentName topActivity = runningTasks.get(0).topActivity; + final String topPackage = topActivity.getPackageName(); + final boolean topPackageEqualsToClient = + topPackage == null + || topActivity.getPackageName().contentEquals(clientPackage); + + // b/339532378: If it's ConfirmDeviceCredentialActivity, we need to check further on + // class name. + final String clientClassNameForCDCA = + mCurrentDialog.getClassNameIfItIsConfirmDeviceCredentialActivity(); + final boolean isClientCDCA = clientClassNameForCDCA != null; + final String topClassName = topActivity.getClassName(); + final boolean isCDCAWithWrongTopClass = + isClientCDCA + && !(topClassName == null + || topClassName.contentEquals(clientClassNameForCDCA)); + + final boolean isInBackground = + !(isSystemApp || topPackageEqualsToClient) || isCDCAWithWrongTopClass; + + Log.w(TAG, "isInBackground " + isInBackground); + return isInBackground; + } + return false; + } + /** * Whether all fingerprint authentictors have been registered. */ diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java index 3cfc6f280110..c30d058db5a0 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java @@ -160,6 +160,12 @@ public interface AuthDialog extends Dumpable { long getRequestId(); /** + * Get the class name of ConfirmDeviceCredentialActivity. Returns null if the direct caller is + * not ConfirmDeviceCredentialActivity. + */ + String getClassNameIfItIsConfirmDeviceCredentialActivity(); + + /** * Animate to credential UI. Typically called after biometric is locked out. */ void animateToCredentialUI(boolean isError); |