Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6096c017 authored by Hao Dong's avatar Hao Dong
Browse files

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
Change-Id: I722e285cd15869799b9fadd2324014cf3c6d44ad
Merged-In: I722e285cd15869799b9fadd2324014cf3c6d44ad
parent 82765b2f
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -465,6 +465,20 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
        }
        // LINT.ThenChange(frameworks/base/core/java/android/hardware/biometrics/PromptInfo.java)

        /**
         * 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}.
         *
+20 −0
Original line number Diff line number Diff line
@@ -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);
    }

    // LINT.IfChange
@@ -127,6 +130,8 @@ public class PromptInfo implements Parcelable {
            return true;
        } else if (mIgnoreEnrollmentState) {
            return true;
        } else if (mClassNameIfItIsConfirmDeviceCredentialActivity != null) {
            return true;
        }
        return false;
    }
@@ -228,6 +233,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() {
@@ -309,4 +321,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;
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -806,6 +806,10 @@ public class AuthContainerView extends LinearLayout
        return mConfig.mOpPackageName;
    }

    @Override
    public String getClassNameIfItIsConfirmDeviceCredentialActivity() {
        return  mConfig.mPromptInfo.getClassNameIfItIsConfirmDeviceCredentialActivity();
    }
    @Override
    public long getRequestId() {
        return mConfig.mRequestId;
+12 −14
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.TaskStackListener;
import android.content.BroadcastReceiver;
@@ -188,7 +187,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
    final TaskStackListener mTaskStackListener = new TaskStackListener() {
        @Override
        public void onTaskStackChanged() {
            if (!isOwnerInForeground()) {
            if (isOwnerInBackground()) {
                mHandler.post(AuthController.this::cancelIfOwnerIsNotInForeground);
            }
        }
@@ -228,21 +227,20 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
        }
    }

    private boolean isOwnerInForeground() {
    private boolean isOwnerInBackground() {
        if (mCurrentDialog != null) {
            final String clientPackage = mCurrentDialog.getOpPackageName();
            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.w(TAG, "Evicting client due to: " + topPackage);
                    return false;
                }
            final String clientClassNameIfItIsConfirmDeviceCredentialActivity =
                    mCurrentDialog.getClassNameIfItIsConfirmDeviceCredentialActivity();
            final boolean isInBackground = Utils.isSystemAppOrInBackground(mActivityTaskManager,
                    mContext, clientPackage,
                    clientClassNameIfItIsConfirmDeviceCredentialActivity);
            if (isInBackground) {
                Log.w(TAG, "Evicting client due to top activity is not : " + clientPackage);
            }
            return isInBackground;
        }
        return true;
        return false;
    }

    private void cancelIfOwnerIsNotInForeground() {
@@ -1258,7 +1256,7 @@ public class AuthController implements CoreStartable, CommandQueue.Callbacks,
        }
        mCurrentDialog = newDialog;

        if (!promptInfo.isAllowBackgroundAuthentication() && !isOwnerInForeground()) {
        if (!promptInfo.isAllowBackgroundAuthentication() && isOwnerInBackground()) {
            cancelIfOwnerIsNotInForeground();
        } else {
            mCurrentDialog.show(mWindowManager, savedState);
+6 −0
Original line number Diff line number Diff line
@@ -156,6 +156,12 @@ public interface AuthDialog extends Dumpable {
     */
    String getOpPackageName();

    /**
     * Get the class name of ConfirmDeviceCredentialActivity. Returns null if the direct caller is
     * not ConfirmDeviceCredentialActivity.
     */
    String getClassNameIfItIsConfirmDeviceCredentialActivity();

    /** The requestId of the underlying operation within the framework. */
    long getRequestId();

Loading