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

Commit 92ff273e authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez
Browse files

Adding MSDL Feedback to the Pin bouncer.

MSDL haptic feedback is being added to interactions in the pin bouncer.
These include tapping the numpad keys, tapping and long-pressing the
delete key, and successful and failed authentication when the pin is
submitted using the return key. In addition, the tapping feedback is
added to the Emergency button.

Test: atest KeyguardAbsKeyInputViewControllerTest
Test: manual. Performing all interactions above and verifying that the
  correct haptics are delivered when the flag is on.
Flag: com.android.systemui.msdl_feedback
Bug: 361321945
Bug: 352600066
Change-Id: I481ae644070eb8da51530bdf7463d1c51fd8b7b5
parent 92232a80
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
                fakeFeatureFlags,
                mSelectedUserInteractor,
                keyguardKeyboardInteractor,
                null,
            )
    }

+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
                mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
                mKeyguardMessageAreaControllerFactory, mLatencyTracker, mLiftToactivateListener,
                mEmergencyButtonController, mFalsingCollector, featureFlags,
                mSelectedUserInteractor, keyguardKeyboardInteractor) {
                mSelectedUserInteractor, keyguardKeyboardInteractor, null) {
            @Override
            public void onResume(int reason) {
                super.onResume(reason);
+1 −0
Original line number Diff line number Diff line
@@ -239,6 +239,7 @@ class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
                featureFlags,
                mSelectedUserInteractor,
                keyguardKeyboardInteractor,
                null,
            )

        kosmos = testKosmos()
+29 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.keyguard

import android.os.VibrationAttributes
import com.google.android.msdl.domain.InteractionProperties

/**
 * This class represents the set of [InteractionProperties] that only hold [VibrationAttributes] for
 * the case of user authentication.
 */
data class AuthInteractionProperties(
    override val vibrationAttributes: VibrationAttributes =
        VibrationAttributes.createForUsage(VibrationAttributes.USAGE_COMMUNICATION_REQUEST)
) : InteractionProperties
+24 −1
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@ package com.android.keyguard;
import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL;
import static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL_UNLOCKED;
import static com.android.keyguard.KeyguardAbsKeyInputView.MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT;
import static com.android.systemui.Flags.msdlFeedback;

import android.annotation.Nullable;
import android.content.res.ColorStateList;
import android.os.AsyncTask;
import android.os.CountDownTimer;
@@ -40,6 +42,9 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.res.R;
import com.android.systemui.user.domain.interactor.SelectedUserInteractor;

import com.google.android.msdl.data.model.MSDLToken;
import com.google.android.msdl.domain.MSDLPlayer;

import java.util.HashMap;
import java.util.Map;

@@ -55,6 +60,8 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
    protected AsyncTask<?, ?, ?> mPendingLockCheck;
    protected boolean mResumed;
    protected boolean mLockedOut;
    @Nullable
    protected MSDLPlayer mMSDLPlayer;

    private final KeyDownListener mKeyDownListener = (keyCode, keyEvent) -> {
        // Fingerprint sensor sends a KeyEvent.KEYCODE_UNKNOWN.
@@ -81,7 +88,8 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
            KeyguardMessageAreaController.Factory messageAreaControllerFactory,
            LatencyTracker latencyTracker, FalsingCollector falsingCollector,
            EmergencyButtonController emergencyButtonController,
            FeatureFlags featureFlags, SelectedUserInteractor selectedUserInteractor) {
            FeatureFlags featureFlags, SelectedUserInteractor selectedUserInteractor,
            @Nullable MSDLPlayer msdlPlayer) {
        super(view, securityMode, keyguardSecurityCallback, emergencyButtonController,
                messageAreaControllerFactory, featureFlags, selectedUserInteractor);
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -89,6 +97,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
        mLatencyTracker = latencyTracker;
        mFalsingCollector = falsingCollector;
        mEmergencyButtonController = emergencyButtonController;
        mMSDLPlayer = msdlPlayer;
    }

    abstract void resetState();
@@ -178,6 +187,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
    void onPasswordChecked(int userId, boolean matched, int timeoutMs, boolean isValidPassword) {
        boolean dismissKeyguard = mSelectedUserInteractor.getSelectedUserId() == userId;
        if (matched) {
            playAuthenticationHaptics(/* unlock= */true);
            getKeyguardSecurityCallback().reportUnlockAttempt(userId, true, 0);
            if (dismissKeyguard) {
                mDismissing = true;
@@ -185,6 +195,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
                getKeyguardSecurityCallback().dismiss(true, userId, getSecurityMode());
            }
        } else {
            playAuthenticationHaptics(/* unlock= */false);
            mView.resetPasswordText(true /* animate */, false /* announce deletion if no match */);
            if (isValidPassword) {
                getKeyguardSecurityCallback().reportUnlockAttempt(userId, false, timeoutMs);
@@ -201,6 +212,18 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
        }
    }

    private void playAuthenticationHaptics(boolean unlock) {
        if (!msdlFeedback() || mMSDLPlayer == null) return;

        MSDLToken token;
        if (unlock) {
            token = MSDLToken.UNLOCK;
        } else {
            token = MSDLToken.FAILURE;
        }
        mMSDLPlayer.playToken(token, mAuthInteractionProperties);
    }

    protected void startErrorAnimation() { /* no-op */ }

    protected void verifyPasswordAndUnlock() {
Loading