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

Commit 1dcfaa3a authored by Joshua Mccloskey's avatar Joshua Mccloskey Committed by Android (Google) Code Review
Browse files

Merge "Added FingerprintInteractiveToAuthProvider"

parents 68930017 b4739d67
Loading
Loading
Loading
Loading
+16 −35
Original line number Diff line number Diff line
@@ -140,6 +140,7 @@ import com.android.settingslib.fuelgauge.BatteryStatus;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
@@ -169,6 +170,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.Executor;
@@ -329,13 +331,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
            mCallbacks = Lists.newArrayList();
    private ContentObserver mDeviceProvisionedObserver;
    private ContentObserver mSfpsRequireScreenOnToAuthPrefObserver;
    private final ContentObserver mTimeFormatChangeObserver;

    private boolean mSwitchingUser;

    private boolean mDeviceInteractive;
    private boolean mSfpsRequireScreenOnToAuthPrefEnabled;
    private final SubscriptionManager mSubscriptionManager;
    private final TelephonyListenerManager mTelephonyListenerManager;
    private final TrustManager mTrustManager;
@@ -368,6 +368,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
    private boolean mLogoutEnabled;
    private boolean mIsFaceEnrolled;
    private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    private FingerprintInteractiveToAuthProvider mFingerprintInteractiveToAuthProvider;

    /**
     * Short delay before restarting fingerprint authentication after a successful try. This should
@@ -2039,7 +2040,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            @Nullable FaceManager faceManager,
            @Nullable FingerprintManager fingerprintManager,
            @Nullable BiometricManager biometricManager,
            FaceWakeUpTriggersConfig faceWakeUpTriggersConfig) {
            FaceWakeUpTriggersConfig faceWakeUpTriggersConfig,
            Optional<FingerprintInteractiveToAuthProvider> interactiveToAuthProvider) {
        mContext = context;
        mSubscriptionManager = subscriptionManager;
        mUserTracker = userTracker;
@@ -2303,30 +2305,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                Settings.System.getUriFor(Settings.System.TIME_12_24),
                false, mTimeFormatChangeObserver, UserHandle.USER_ALL);

        updateSfpsRequireScreenOnToAuthPref();
        mSfpsRequireScreenOnToAuthPrefObserver = new ContentObserver(mHandler) {
            @Override
            public void onChange(boolean selfChange) {
                updateSfpsRequireScreenOnToAuthPref();
            }
        };

        mContext.getContentResolver().registerContentObserver(
                mSecureSettings.getUriFor(
                        Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED),
                false,
                mSfpsRequireScreenOnToAuthPrefObserver,
                getCurrentUser());
    }

    protected void updateSfpsRequireScreenOnToAuthPref() {
        final int defaultSfpsRequireScreenOnToAuthValue =
                mContext.getResources().getBoolean(
                        com.android.internal.R.bool.config_requireScreenOnToAuthEnabled) ? 1 : 0;
        mSfpsRequireScreenOnToAuthPrefEnabled = mSecureSettings.getIntForUser(
                Settings.Secure.SFPS_REQUIRE_SCREEN_ON_TO_AUTH_ENABLED,
                defaultSfpsRequireScreenOnToAuthValue,
                getCurrentUser()) != 0;
        mFingerprintInteractiveToAuthProvider = interactiveToAuthProvider.orElse(null);
    }

    private void initializeSimState() {
@@ -2721,8 +2700,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

        boolean shouldListenSideFpsState = true;
        if (isSideFps) {
            final boolean interactiveToAuthEnabled =
                    mFingerprintInteractiveToAuthProvider != null &&
                            mFingerprintInteractiveToAuthProvider.isEnabled(getCurrentUser());
            shouldListenSideFpsState =
                    mSfpsRequireScreenOnToAuthPrefEnabled ? isDeviceInteractive() : true;
                    interactiveToAuthEnabled ? isDeviceInteractive() : true;
        }

        boolean shouldListen = shouldListenKeyguardState && shouldListenUserState
@@ -3837,11 +3819,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            mContext.getContentResolver().unregisterContentObserver(mTimeFormatChangeObserver);
        }

        if (mSfpsRequireScreenOnToAuthPrefObserver != null) {
            mContext.getContentResolver().unregisterContentObserver(
                    mSfpsRequireScreenOnToAuthPrefObserver);
        }

        try {
            ActivityManager.getService().unregisterUserSwitchObserver(mUserSwitchObserver);
        } catch (RemoteException e) {
@@ -3919,8 +3896,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                pw.println("        sfpsEnrolled=" + isSfpsEnrolled());
                pw.println("        shouldListenForSfps=" + shouldListenForFingerprint(false));
                if (isSfpsEnrolled()) {
                    pw.println("        mSfpsRequireScreenOnToAuthPrefEnabled="
                        + mSfpsRequireScreenOnToAuthPrefEnabled);
                    final boolean interactiveToAuthEnabled =
                                    mFingerprintInteractiveToAuthProvider != null &&
                                            mFingerprintInteractiveToAuthProvider
                                            .isEnabled(getCurrentUser());
                    pw.println("        interactiveToAuthEnabled="
                            + interactiveToAuthEnabled);
                }
            }
            new DumpsysTableLogger(
+27 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.biometrics;

/** Provides the status of the interactive to auth feature. */
public interface FingerprintInteractiveToAuthProvider {
    /**
     *
     * @param userId the user Id.
     * @return true if the InteractiveToAuthFeature is enabled, false if disabled.
     */
    boolean isEnabled(int userId);
}
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.systemui.BootCompleteCacheImpl;
import com.android.systemui.appops.dagger.AppOpsModule;
import com.android.systemui.assist.AssistModule;
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
import com.android.systemui.biometrics.UdfpsDisplayModeProvider;
import com.android.systemui.biometrics.dagger.BiometricsModule;
import com.android.systemui.biometrics.dagger.UdfpsModule;
@@ -221,6 +222,9 @@ public abstract class SystemUIModule {
    @BindsOptionalOf
    abstract AlternateUdfpsTouchProvider optionalUdfpsTouchProvider();

    @BindsOptionalOf
    abstract FingerprintInteractiveToAuthProvider optionalFingerprintInteractiveToAuthProvider();

    @SysUISingleton
    @Binds
    abstract SystemClock bindSystemClock(SystemClockImpl systemClock);
+7 −5
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ import com.android.keyguard.KeyguardUpdateMonitor.BiometricAuthenticated;
import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.log.SessionTracker;
@@ -143,6 +144,7 @@ import org.mockito.internal.util.reflection.FieldSetter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;

@@ -234,6 +236,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
    @Mock
    private GlobalSettings mGlobalSettings;
    private FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;
    @Mock
    private FingerprintInteractiveToAuthProvider mInteractiveToAuthProvider;


    private final int mCurrentUserId = 100;
@@ -1259,8 +1263,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
        when(mAuthController.isSfpsEnrolled(anyInt())).thenReturn(true);

        // WHEN require screen on to auth is disabled, and keyguard is not awake
        when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).thenReturn(0);
        mKeyguardUpdateMonitor.updateSfpsRequireScreenOnToAuthPref();
        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);

        mContext.getOrCreateTestableResources().addOverride(
                com.android.internal.R.bool.config_requireScreenOnToAuthEnabled, true);
@@ -1280,8 +1283,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isTrue();

        // WHEN require screen on to auth is enabled, and keyguard is not awake
        when(mSecureSettings.getIntForUser(anyString(), anyInt(), anyInt())).thenReturn(1);
        mKeyguardUpdateMonitor.updateSfpsRequireScreenOnToAuthPref();
        when(mInteractiveToAuthProvider.isEnabled(anyInt())).thenReturn(false);

        // THEN we shouldn't listen for sfps when screen off, because require screen on is enabled
        assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(false)).isFalse();
@@ -2406,7 +2408,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
                    mPowerManager, mTrustManager, mSubscriptionManager, mUserManager,
                    mDreamManager, mDevicePolicyManager, mSensorPrivacyManager, mTelephonyManager,
                    mPackageManager, mFaceManager, mFingerprintManager, mBiometricManager,
                    mFaceWakeUpTriggersConfig);
                    mFaceWakeUpTriggersConfig, Optional.of(mInteractiveToAuthProvider));
            setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
        }

+4 −90
Original line number Diff line number Diff line
@@ -16,15 +16,11 @@

package com.android.server.biometrics.sensors.fingerprint.aidl;

import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_START;
import static android.hardware.biometrics.BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_VENDOR;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.TaskStackListener;
import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
import android.hardware.biometrics.BiometricManager.Authenticators;
@@ -94,7 +90,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
    private long mSideFpsLastAcquireStartTime;
    private Runnable mAuthSuccessRunnable;
    private final Clock mClock;
    private boolean mDidFinishSfps;

    FingerprintAuthenticationClient(
            @NonNull Context context,
@@ -204,9 +199,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>

    @Override
    protected void handleLifecycleAfterAuth(boolean authenticated) {
        if (authenticated && !mDidFinishSfps) {
        if (authenticated) {
            mCallback.onClientFinished(this, true /* success */);
            mDidFinishSfps = true;
        }
    }

@@ -216,13 +210,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
        return false;
    }

    public void handleAuthenticate(
    @Override
    public void onAuthenticated(
            BiometricAuthenticator.Identifier identifier,
            boolean authenticated,
            ArrayList<Byte> token) {
        if (authenticated && mSensorProps.isAnySidefpsType()) {
            Slog.i(TAG, "(sideFPS): No power press detected, sending auth");
        }
        super.onAuthenticated(identifier, authenticated, token);
        if (authenticated) {
            mState = STATE_STOPPED;
@@ -232,75 +224,14 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
        }
    }

    @Override
    public void onAuthenticated(
            BiometricAuthenticator.Identifier identifier,
            boolean authenticated,
            ArrayList<Byte> token) {

        mHandler.post(
                () -> {
                    long delay = 0;
                    if (authenticated && mSensorProps.isAnySidefpsType()) {
                        delay = isKeyguard() ? mWaitForAuthKeyguard : mWaitForAuthBp;

                        if (mSideFpsLastAcquireStartTime != -1) {
                            delay = Math.max(0,
                                    delay - (mClock.millis() - mSideFpsLastAcquireStartTime));
                        }

                        Slog.i(TAG, "(sideFPS) Auth succeeded, sideFps "
                                + "waiting for power until: " + delay + "ms");
                    }

                    if (mHandler.hasMessages(MESSAGE_FINGER_UP)) {
                        Slog.i(TAG, "Finger up detected, sending auth");
                        delay = 0;
                    }

                    mAuthSuccessRunnable =
                            () -> handleAuthenticate(identifier, authenticated, token);
                    mHandler.postDelayed(
                            mAuthSuccessRunnable,
                            MESSAGE_AUTH_SUCCESS,
                            delay);
                });
    }

    @Override
    public void onAcquired(@FingerprintAcquired int acquiredInfo, int vendorCode) {
        // For UDFPS, notify SysUI with acquiredInfo, so that the illumination can be turned off
        // for most ACQUIRED messages. See BiometricFingerprintConstants#FingerprintAcquired
        mSensorOverlays.ifUdfps(controller -> controller.onAcquired(getSensorId(), acquiredInfo));
        super.onAcquired(acquiredInfo, vendorCode);
        if (mSensorProps.isAnySidefpsType()) {
            if (acquiredInfo == FINGERPRINT_ACQUIRED_START) {
                mSideFpsLastAcquireStartTime = mClock.millis();
            }
            final boolean shouldLookForVendor =
                    mSkipWaitForPowerAcquireMessage == FINGERPRINT_ACQUIRED_VENDOR;
            final boolean acquireMessageMatch = acquiredInfo == mSkipWaitForPowerAcquireMessage;
            final boolean vendorMessageMatch = vendorCode == mSkipWaitForPowerVendorAcquireMessage;
            final boolean ignorePowerPress =
                    acquireMessageMatch && (!shouldLookForVendor || vendorMessageMatch);

            if (ignorePowerPress) {
                Slog.d(TAG, "(sideFPS) onFingerUp");
                mHandler.post(() -> {
                    if (mHandler.hasMessages(MESSAGE_AUTH_SUCCESS)) {
                        Slog.d(TAG, "(sideFPS) skipping wait for power");
                        mHandler.removeMessages(MESSAGE_AUTH_SUCCESS);
                        mHandler.post(mAuthSuccessRunnable);
                    } else {
                        mHandler.postDelayed(() -> {
                        }, MESSAGE_FINGER_UP, mFingerUpIgnoresPower);
                    }
                });
            }
        }
        PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
        pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());

    }

    @Override
@@ -495,22 +426,5 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
    }

    @Override
    public void onPowerPressed() {
        if (mSensorProps.isAnySidefpsType()) {
            Slog.i(TAG, "(sideFPS): onPowerPressed");
            mHandler.post(() -> {
                if (mDidFinishSfps) {
                    return;
                }
                Slog.i(TAG, "(sideFPS): finishing auth");
                // Ignore auths after a power has been detected
                mHandler.removeMessages(MESSAGE_AUTH_SUCCESS);
                // Do not call onError() as that will send an additional callback to coex.
                mDidFinishSfps = true;
                onErrorInternal(BiometricConstants.BIOMETRIC_ERROR_POWER_PRESSED, 0, true);
                stopHalOperation();
                mSensorOverlays.hide(getSensorId());
            });
        }
    }
    public void onPowerPressed() { }
}
Loading