summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hao Dong <spdonghao@google.com> 2024-10-11 03:54:02 +0000
committer Hao Dong <spdonghao@google.com> 2025-01-08 23:09:03 -0800
commite1c25c186f9fb056fefe089167ee8f3678ecd917 (patch)
treeb0afec5f76afcb974e8015add2a6907c0e4b1818
parent8a7a8c8a40a65baa295c1ad5dced4e78b86530fd (diff)
Fix settings activity showing background bp when
createConfirmDeviceCredentialIntent() API is used. If the app uses createConfirmDeviceCredentialIntent(), ConfirmDeviceCredentialActivity is the top activity which has "settings" as package name. Then if the app switches to settings, since previous foreground check only checks package name, biometric prompt isn't cancelled. This CL adds a class name check for this case. Flag: EXEMPT bugfix Bug: 339532378 Test: manual test with sample app on emulator Test: atest BiometricActivityTests#testConfirmDeviceCredentialActivityDismiss_whenSwitchToSettings Change-Id: I722e285cd15869799b9fadd2324014cf3c6d44ad Merged-In: I722e285cd15869799b9fadd2324014cf3c6d44ad Merged-In: I26d8f4713573ab18ef3f83813aaef52ede910b8d
-rw-r--r--core/java/android/hardware/biometrics/BiometricPrompt.java14
-rw-r--r--core/java/android/hardware/biometrics/PromptInfo.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java71
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java6
5 files changed, 97 insertions, 19 deletions
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 520234bcf050..a3fe48a31de6 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -433,6 +433,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 2742f0effde6..601ba38a7bb7 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -47,6 +47,7 @@ public class PromptInfo implements Parcelable {
private boolean mAllowBackgroundAuthentication;
private boolean mIgnoreEnrollmentState;
private boolean mIsForLegacyFingerprintManager = false;
+ private String mClassNameIfItIsConfirmDeviceCredentialActivity = null;
public PromptInfo() {
@@ -70,6 +71,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>() {
@@ -108,6 +110,7 @@ public class PromptInfo implements Parcelable {
dest.writeBoolean(mAllowBackgroundAuthentication);
dest.writeBoolean(mIgnoreEnrollmentState);
dest.writeBoolean(mIsForLegacyFingerprintManager);
+ dest.writeString(mClassNameIfItIsConfirmDeviceCredentialActivity);
}
public boolean containsTestConfigurations() {
@@ -119,6 +122,8 @@ public class PromptInfo implements Parcelable {
return true;
} else if (mAllowBackgroundAuthentication) {
return true;
+ } else if (mClassNameIfItIsConfirmDeviceCredentialActivity != null) {
+ return true;
}
return false;
}
@@ -213,6 +218,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() {
@@ -290,4 +302,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 fd37b3509a4e..a6d8e4932240 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -689,6 +689,11 @@ public class AuthContainerView extends LinearLayout
}
@Override
+ public String getClassNameIfItIsConfirmDeviceCredentialActivity() {
+ return mConfig.mPromptInfo.getClassNameIfItIsConfirmDeviceCredentialActivity();
+ }
+
+ @Override
public void animateToCredentialUI() {
mBiometricView.startTransitionToCredentialUI();
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 03cc28c41917..7c7716b8323a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -25,6 +25,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;
@@ -206,25 +207,18 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
private void cancelIfOwnerIsNotInForeground() {
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;
- mOrientationListener.disable();
-
- if (mReceiver != null) {
- mReceiver.onDialogDismissed(
- BiometricPrompt.DISMISSED_REASON_USER_CANCEL,
- null /* credentialAttestation */);
- mReceiver = null;
- }
+ if (isOwnerInBackground()) {
+ Log.w(TAG, "Evicting client due to top activity is not : "
+ + mCurrentDialog.getOpPackageName());
+ mCurrentDialog.dismissWithoutCallback(true /* animate */);
+ mCurrentDialog = null;
+ mOrientationListener.disable();
+
+ if (mReceiver != null) {
+ mReceiver.onDialogDismissed(
+ BiometricPrompt.DISMISSED_REASON_USER_CANCEL,
+ null /* credentialAttestation */);
+ mReceiver = null;
}
}
} catch (RemoteException e) {
@@ -233,6 +227,45 @@ public class AuthController extends SystemUI implements 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;
+ }
+
/**
* Adds a callback. See {@link Callback}.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index fa5213e94081..dd4eb99cc2c7 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -148,6 +148,12 @@ public interface AuthDialog {
String getOpPackageName();
/**
+ * 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();